Регулярное выражение C #: отрицательный упущение завершается неудачей с параметром в одну строку - PullRequest
1 голос
/ 01 июня 2010

Я пытаюсь выяснить, почему регулярное выражение с отрицательным взглядом в будущее не срабатывает, когда включена опция «одна строка».

Пример (упрощенный):

<source>Test 1</source>
<source>Test 2</source>
<target>Result 2</target>
<source>Test 3</source>

Это:

<source>(?!.*<source>)(.*?)</source>(?!\s*<target)

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

(?-s:<source>(?!.*<source>)(.*?)</source>(?!\s*<target))

Насколько я понимаю, однострочный режим просто разрешает точку "."соответствовать новым строкам, и я не понимаю, почему это повлияет на выражение выше.

Может кто-нибудь объяснить, чего мне здесь не хватает?

::::::::::::::::::::::

РЕДАКТИРОВАТЬ: (?!. *) является негативным прогнозом , а не группой захвата.

 <source>(?!.*?<source>)(.*?)</source>(?!\s*<target)

ТАКЖЕ НЕ УДАЕТСЯ, если включен однострочный режим, поэтому, похоже, это не проблема жадности.Попробуйте это в конструкторе Regex (например, в Expresso или Rad regex):

При отключении одной строки оно соответствует (как и ожидалось):

<source>Test 1</source>    
<source>Test 3</source>

При включении одной строки:

<source>Test 3</source>

Я не понимаю, почему он также не соответствует первому: он не содержит первого негативного взгляда вперед, поэтому он должен соответствовать выражению.

Ответы [ 2 ]

2 голосов
/ 01 июня 2010

Я считаю, что это то, что вы ищете:

<source>((?:(?!</?source>).)*)</source>(?!\s*<target)

Идея состоит в том, что вы сопоставляете каждый символ по одному, но только после того, как убедитесь, что это не первый символ </source>. Кроме того, с добавлением /? к просмотру вам не нужно использовать негладкий квантификатор.

2 голосов
/ 01 июня 2010

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

<source>(?!.*<source>)(.*?)</source>(?!\s*<target)
        ^^^^^^^^^^^^^^

Теперь давайте рассмотрим, что здесь делает (?!.*<source>): это точка зрения, которая говорит, что1005 * NO соответствует .*<source> с этой позиции.

Ну, в однострочном режиме . соответствует всему.После сопоставления первых двух <source>, IS на самом деле .*<source>!Таким образом, отрицательный прогноз не выполняется в течение первых двух <source>.

. В последнем <source>, .*<source> больше не совпадает, поэтому отрицательный прогноз выполняется успешно.Остальная часть шаблона также успешно выполняется, и поэтому вы получаете <source>Test 3</source> только в однострочном режиме.

...