Отрицательный просмотр вперед, которому предшествует. * - PullRequest
1 голос
/ 06 мая 2020

Я хочу выделить весь текст в {}, но только если там нет \status…{}.

Примеры, которые должны соответствовать:

\subsection{Hello}                -> "\subsection”, "Hello"
\section{Foobar}                  -> "\section", "Foobar"
\subsubsection{This is a Triumph} -> "\subsubsection", "This is a Triumph"

Примеры, которые должны not match:

\subsection{Hello\statusdone{}}
\section{Hello World\statuswip{}}
\section{Everything\statusproofreading{}}

Я думал, что для этого идеально подойдет отрицательный просмотр вперед:

(\\.*section)\{(.*)(?!\\status.*)\}

но они совпадают:

\subsection{Hello\statusdone{}}           -> "\subsection", "Hello\statusdone{}"
\section{Hello World\statuswip{}}         -> "\section", "Hello World\statuswip{}"
\section{Everything\statusproofreading{}} -> "\section", "Everything\statusproofreading{}"

I подозреваю, что это из-за .*, предшествующего отрицательному просмотру вперед. Если я заменю его на, egg, Hello в следующем регулярном выражении:

(\\.*section)\{(Hello)(?!\\status.*)\}

Он правильно не соответствует первому отрицательному примеру \subsection{Hello\statusdone{}}.

Как мне обойти это ?

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Regex не имеет тестера иглы не внутри стога сена. (Или, по крайней мере, не распространенная его реализация.)

Вы сбиваете с толку способ работы утверждений нулевой ширины. Это ЛЮБОЙ матч, а не ВСЕ. В тот момент, когда совпадает первая позиция, она подходит и возвращает ее.

Перед вами работа в два прохода. Первая проблема заключается в том, что у вас нет регулярного языка здесь, в LaTeX или чем-то еще, а это означает, что регулярные выражения не будут работать с произвольным текстом.

\section{\math{\ref{\status{asfd}}}} и последний "}" вы match, et c.

Для этого вам нужен синтаксический анализатор, а не регулярное выражение. Извините.

1 голос
/ 06 мая 2020

Вы должны переместить отрицательный опережающий просмотр раньше в шаблоне, чтобы он проверял наличие этой подстроки до того, как будет использована вся строка (.*).

Вы можете используйте:

\\.*section\{((?!.*\\status.*\{\})[^}]+)}

Live demo здесь .

...