почему дополнение поиска не работает? - PullRequest
2 голосов
/ 29 ноября 2011

Я ожидаю, что "abc" =~ /\Aabc\z/gc; будет ложным, поскольку /c существует, как в этом случае:

$pathname =˜ tr/a-zA-Z/_/cs; # change non-(ASCII)alphas to single underbar

Но оказывается, что true, любой может объяснить причину?

Ответы [ 3 ]

8 голосов
/ 29 ноября 2011

См. perlretut о том, что на самом деле делает /c (Применительно к оператору соответствия регулярного выражения оно не дополняет, как это было бы с tr///). Транслитерация не является регулярным выражением, и регулярное выражение не является транслитерацией.

От perlretut:

Неудачное совпадение или изменение целевой строки сбрасывает позицию. Если Вы не хотите, чтобы сброс позиции после сбоя совпадал, добавьте // c , как в / regexp / gc.

Практически такой же отрывок появляется в perlrequick.

perlre делает поиск немного сложнее, но вот что он говорит:

г и с Глобальное сопоставление и сохранение текущей позиции после неудачного сопоставления. В отличие от i, m, s и x, эти два флага влияют на то, как используется регулярное выражение а не само регулярное выражение. См. Использование регулярных выражений в Perl в perlretut для дальнейшего объяснения модификаторов g и c.

6 голосов
/ 29 ноября 2011

/c не выполняет сопоставление «дополнения»:)

"abc" !~ /abc/;  # false

Запретить abc в любом месте строки, которую вы могли бы сделать

/((?!abc).)*\z/

но это было бы гораздо менее эффективно

РЕДАКТИРОВАТЬ:

/gc модификатор : (из perldoc perlretut)

Неудачное совпадение или изменение целевой строки сбрасывает позицию.Если вы не хотите, чтобы сброс позиции после сбоя совпадал, добавьте //c, как в /regexp/gc.Текущая позиция в строке связана со строкой, а не с регулярным выражением.Это означает, что разные строки имеют разные позиции, и их соответствующие позиции могут быть установлены или считаны независимо.

2 голосов
/ 30 ноября 2011

Если вы хотите проверить, не находится ли что-то в строке, я рекомендую

$str !~ /abc/

, что сокращенно от

!( $str =~ /abc/ )

. Вы также можете использовать следующее, но этоненужно сложный (и медленный?):

$str =~ /^(?:(?!abc).)*\z/s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...