Не могли бы вы объяснить, почему это регулярное выражение не работает? - PullRequest
3 голосов
/ 17 июня 2011
>>> d = "Batman,Superman"
>>> m = re.search("(?<!Bat)\w+",d)
>>> m.group(0)
'Batman'

Почему группа (0) не соответствует Супермену? В этом руководстве написано:

(?

Ответы [ 5 ]

6 голосов
/ 17 июня 2011

Batman не непосредственно предшествует на Bat, так что это соответствует первому.На самом деле, ни один не является Superman;в вашей строке есть запятая, которая отлично подходит для того, чтобы этот RE совпадал, но в любом случае это не совпадает, потому что в строке можно сопоставить раньше.

Возможно, это объяснит лучше: если строка была Batman и вы пытались найти совпадение с m, RE не будет совпадать до тех пор, пока символ не будет (после совпадения an), потому что это единственное место встрока, которой предшествует Bat.

1 голос
/ 17 июня 2011

Чтобы сделать то, что вы хотите, вы должны ограничить регулярное выражение для соответствия 'man'; в противном случае, как отмечали другие, \w жадно сопоставляется с чем угодно, включая 'Batman'. Как в:

>>> re.search("\w+(?<!Bat)man","Batman,Superman").group(0)
'Superman'
1 голос
/ 17 июня 2011

Вы ищете первый набор из одного или нескольких буквенно-цифровых символов (\w+), которому не предшествует 'Bat'. Бэтмен первый такой матч. (Обратите внимание, что отрицательные утверждения за задним числом могут соответствовать началу строки.)

1 голос
/ 17 июня 2011

На простом уровне движок регулярных выражений запускается слева от строки и постепенно перемещается вправо, пытаясь сопоставить ваш паттерн (представьте, что курсор перемещается по строке).В случае обхода, при каждой остановке курсора указывается обход, и если он равен true, двигатель продолжает пытаться сопоставить.Как только двигатель сможет соответствовать вашему шаблону, он вернет соответствие.

В позиции 0 вашей строки (т. Е. До B в Batman) подтверждение выполнено успешно, поскольку Bat отсутствует до текущей позиции - таким образом, \w+ может соответствоватьвсе слово Batman (помните, что регулярные выражения по своей природе жадные - т.е. будут соответствовать как можно больше).

См. эту страницу для получения дополнительной информации о движкеВнутренние органы.


Чтобы достичь того, что вы хотели, вместо этого вы можете использовать что-то вроде:

\b(?!Bat)\w+

В этом шаблоне движок будет соответствовать границе слова (\b) 1 , за которым следуют один или несколько символов слова, с утверждением, что символы слова не начинаются с Bat. lookahead используется вместо lookbehind , потому что использование здесь lookbehind будет иметь ту же проблему, что и ваш исходный шаблон;он будет выглядеть перед позицией, следующей непосредственно за границей слова, и поскольку уже определено, что позиция перед курсором является границей слова, отрицательный взгляд за ним всегда будет успешным.

1 Обратите внимание, что границы слов соответствуют границе между \w и \W (т. Е. Между [A-Za-z0-9_] и любым другим символом; он также соответствует ^ и $ якорям ).Если ваши границы должны быть более сложными, вам понадобится другой способ привязки вашего шаблона.

1 голос
/ 17 июня 2011

Из руководства:

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

http://docs.python.org/library/re.html#regular-expression-syntax

...