2016-02-23 4 views
-2

У меня есть проблема, делая Perl-регулярное выражение, чтобы изменить \ характер следуя этим правилам:Perl Regex для MathJax синтаксиса

  1. Последовательность согласования должна начинаться с \(
  2. Он должен заканчиваться \)
  3. Любой \ символ в предыдущей согласованной последовательности следует заменить двойной обратной косой чертой \\

Пример текстовой ссылки:

Se la \probabilità dell'evento\ A è \(\frac{3}{4} \) e la 
probabilità dell'evento B è \(\frac{1}{4}\)  
\(\frac{3}{4} +\frac{3}{4}\) . 
\(\frac{1}{4} - \frac{3}{4}\) . 
\(\frac{3}{16}\) . 
\(\frac{1}{2}\) . 

должны стать:

Se la \probabilità dell'evento\ A è \\(\\frac{3}{4} \\) e la 
probabilità dell'evento B è \\(\\frac{1}{4}\\)  
\\(\\frac{3}{4} +\\frac{3}{4}\\) . 
\\(\\frac{1}{4} - \\frac{3}{4}\\) . 
\\(\\frac{3}{16}\\) . 
\\(\\frac{1}{2}\\) . 

До сих пор это мой лучший выбор:

s/(\\\()(.*)(\\)(.*)(\\\))/\\\\\($2\\\\$4\\\\\)/mg 

, который производит:

Se la \probabilità dell'evento\ A è \\(\\frac{3}{4} \\) e la 
probabilità dell'evento B è \\(\\frac{1}{4}\\)  
\\(\frac{3}{4} +\\frac{3}{4}\\) . 
\\(\frac{1}{4} - \\frac{3}{4}\\) . 
\\(\\frac{3}{16}\\) . 
\\(\\frac{1}{2}\\) . 

Как вы можете см.

\\(\frac{3}{4} +\\frac{3}{4}\\) . 
\\(\frac{1}{4} - \\frac{3}{4}\\) . 

неправ.

Как изменить мое регулярное выражение, чтобы удовлетворить мои потребности?

+4

Это будет правильный вопрос, если после вашего входа и выхода образца он продолжал с, «Я попытался, используя следующий код: ....... но он не смог соответствовать нижеследующий состояние: .......... Как мне изменить свой код, чтобы приспособить это условие? »Как написано, это спецификация работы, которая должна быть выполнена, а не вопрос, требующий руководства по коду, над которым вы работаете. – DavidO

+0

Извините, я забыл добавить свою попытку до сих пор я только что редактировал вопрос – LaboDJ

+0

Его можно эффективно выполнить с помощью '$ string = ~ s/(? x) (?: (?! \ A) \ G [^ \\] * \ K \\ | \\ (? = \()) (? =. *? (? <= \\) \))/\\\\/g; ' – sln

ответ

1

размещая обновленный регулярное выражение с моего оригинала.

Оригинал был валидацией в конце для все побегов.
Посмотрите на него, его можно ускорить, только сделав валидацию
один раз, когда он найдет открывающий блок.

В нижней части находится эталон, который сравнивает два метода.

Обновлено регулярное выражение:

$str =~ s/(?s)(?:(?!\A)\G(?!\))[^\\]*\K\\|\\(?=\(.*?\\\)))/\\\\/g;

Formatted and tested:

(?s)    # Dot-All modifier 
(?:    # Cluster start 
     (?! \A)   # Not beginning of string 
     \G     # G anchor - If matched before, start at end of last match 
     (?! \))   # Last was an escape, so ')' ends the block 
     [^\\]*    # Many non-escape's 
     \K     # Previous is not part of match 
     \\     # A lone escape 
    |     # or, 
         # New Block Check - 
     \\     # A lone escape then, 
     (?=    # One time Validation: 
      \(    # an opening '(' 
      .*?    # anything 
      \\ \)    # then a final '\)' 
    )     # ------------- 
)     # Cluster end 

Benchmark:

Образец \(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \)

Результаты

New Regex: (?s)(?:(?!\A)\G(?!\))[^\\]*\K\\|\\(?=\(.*?\\\))) 
Options: <none> 
Completed iterations: 50/50  (x 1000) 
Matches found per iteration: 31 
Elapsed Time: 1.25 s, 1253.92 ms, 1253924 µs 


Old Regex: (?s)(?:(?!\A)\G[^\\]*\K\\|\\(?=\())(?=.*?(?<=\\)\)) 
Options: <none> 
Completed iterations: 50/50  (x 1000) 
Matches found per iteration: 31 
Elapsed Time: 3.95 s, 3952.31 ms, 3952307 µs 
1

Я тестировал @sln REGEX

s/(?x)(?:(?!\A)\G[^\\]*\K\\|\\(?=\())(?=.*?(?<=\\)\))/\\\\/g; 

И это, кажется, работает, хотя это остается тайной для меня загадка.

Обновление с объяснением

Formatted and tested:

(?s)    # Inline Dot-All modifier 
(?:    # Cluster start 
     (?! \A)   # Not beginning of string 
     \G     # G anchor - If matched before, start at end of last match 
     [^\\]*    # Many non-escape's 
     \K     # Previous is not part of match 
     \\     # A lone escape 
    |     # or, 
         # Start of an opening '\(' 
     \\     # A lone escape 
     (?= \()   # followed by an open parenth 
)     # Cluster end 
(?=    # Lookahead, each match validates a final '\)' 
     .*? 
     (?<= \\) 
     \) 
) 
+1

Измените '(? x)' на '(? s)'. Это не секрет, я обновляю ваше сообщение – sln

+1

Я отправил более быстрый вариант ant regex, если вам интересно. – sln

+0

@sln Да, спасибо большое – LaboDJ

 Смежные вопросы

  • Нет связанных вопросов^_^