Ошибка отрицательного прогноза

Я попробовал это регулярное выражение ^([^i]|i(?!s OK))+\.$ в двух строках ниже.

1. /tmp/tmp.oW75zGUh4S ... is O.

2. /tmp/tmp.oW75zGUh4S ... is OK.

Я ожидаю, что это регулярное выражение будет соответствовать первому, но не второму. Тем не менее, это не соответствует ни одному. Почему?

Если я использую положительный прогноз ^([^i]|i(?=s OK))+\.$, то он соответствует второму, но не первому, и это ожидаемое поведение.


person Dominique Fortin    schedule 05.04.2016    source источник
comment
Каково правило сопоставления?   -  person    schedule 06.04.2016
comment
Работает здесь. Но это больше похоже на то, что вы хотели бы ^.*(?<!is OK.)$, по крайней мере, я думаю, что это более читабельно и, кроме того, проще на обратных трассах.   -  person Wrikken    schedule 06.04.2016
comment
Пример: regex101.com/r/vA6tY8/1   -  person Wrikken    schedule 06.04.2016
comment
(если в источнике не будет точки, как часто я об этом забываю :))   -  person Wrikken    schedule 06.04.2016
comment
Я пробовал Oracle regexp_like. Я попробовал поиск в блокноте ++, попробовал Javascript. Все поддерживают негативный lookhead.   -  person Dominique Fortin    schedule 06.04.2016
comment
@Wrikken, я не ищу взгляда. это не поддерживается в javascript.   -  person Dominique Fortin    schedule 06.04.2016
comment
@Wrikken это не сработает для sdskjfskdfj is OK dkfjslkdfjlks   -  person Dominique Fortin    schedule 06.04.2016
comment
Итак, вы говорите, решить это, не оглядываясь назад? Пфф, плохие реализации :) Вот: ^(.(?!is OK\.$))+$;   -  person Wrikken    schedule 06.04.2016
comment
Ой, подождите, да, без оглядки не получается, вернемся к чертежной доске :)   -  person Wrikken    schedule 06.04.2016
comment
Что ж, опять сбой инструмента: regex101.com/r/vA6tY8/4 (с отрицательным просмотром назад) работает , независимо от того, что там указано в regex101. regex101.com/r/vA6tY8/5 работает только с опережением. Мне все равно, что говорит regex101, я их тестировал :)   -  person Wrikken    schedule 06.04.2016
comment
@Wrikken, точка должна идти после просмотра вперед, а не до, то есть ^((?!is OK\.$).)+$. Чтобы понять, почему, попробуйте сопоставить строку, состоящую только из is OK., что должно привести к ошибке. Ваше регулярное выражение соответствует ему, потому что оно потребляет i до того, как его увидит просмотр вперед. Кроме того, ваше рекурсивное выражение не сработало, потому что вы забыли добавить флаг g. Ни одно из ваших регулярных выражений даже не пыталось сопоставить что-либо после первой строки.   -  person Alan Moore    schedule 29.04.2016


Ответы (1)


После тестирования на regex101.com я обнаружил, что отсутствует \n. Правильное регулярное выражение ^([^i\n]|i(?!s OK))+$.

Спасибо, Вриккен.

Обновление: Просто чтобы объяснить, почему отсутствует \n. ^( ... )+$ является жадным, что означает, что он съест все символы, которые сможет, пока не сможет, а [^i] съест любой символ, который не является i, то есть даже символ конца строки. Кроме того, я ошибочно предположил, что, поскольку $ означает, что совпадение должно заканчиваться концом строки, совпадение не могло пересечь границу конца строки так же, как можно предотвратить пересечение . границу конца строки, установив правильный флаг. $ может означать конец всей строки, но я использовал флаг, чтобы предотвратить это.

person Dominique Fortin    schedule 05.04.2016