2016-09-12 3 views
2

Я хочу иметь регулярное выражение, чтобы найти фразу и два предшествующих ей слова, если есть два слова. Например, у меня есть строка (по одному предложению в строке):Python regex with w не работает

Chevy - моя машина, а Rusty - моя лошадь. Моя машина очень красивая, моя собака красная.

Если я использовать регулярное выражение:

re.finditer(r'[\w+\b|^][\w+\b]my car',txt) 

Я не получаю ни одного матча.

Если я использую регулярное выражение:

re.finditer(r'[\S+\s|^][\S+\s]my car',txt) 

я получаю: 'моя машина' и». Мой автомобиль '(я игнорирую случай и используя многострочный)

Почему регулярное выражение с \ w + \ b не находит ничего? Он должен найти два слова и «мой автомобиль» Как я могу получить два полных слова перед «моей машиной», если есть два слова. Если есть только одно слово, предшествующее моей машине, я должен это получить. Если перед ним нет слов, я должен получить только «свою машину». В моих строках, например, я должен получить: «Chevy моей машина» и «Мой автомобиль» (не предшествующих слов здесь)

+0

Просьба указать точный вызов Python, который вы используете. –

ответ

7

В вашем r'[\w+\b|^][\w+\b]my car регулярного выражения, [\w+\b|^] матчи 1 символ, который является либо слово гольцом, +, backdpace , |, или ^ и [\w+\b] соответствует 1 символу, который является либо символом слова, либо +, либо обратным пространством.

Дело в том, что внутри класса символов, кванторов и много (, но не все) специальные символы соответствуют буквальным символам. Например. [+] соответствует символу плюса, [|^] соответствует либо |, либо ^. Поскольку вы хотите соответствовать последовательности , вам необходимо предоставить последовательность подшаблонов вне класса символов.

Похоже, что вы использовали \b в качестве границы слова, однако \b внутри символьного класса соответствует только символу обратного пробела.

Чтобы найти два слова и «моя машина», вы можете использовать, например

\S+\s+\S+\s+my car 

Смотрите regex demo (здесь, \S+ соответствует одному или более непробельных символы и \s+ матчи 1 или больше пробелов, а 2 вхождения этих двух последовательных подшаблонов соответствуют этим символам как последовательность ).

Для того, чтобы последовательности, прежде чем my car опциональной, просто использовать {0,2} квантор так:

(?:\S+[ \t]+){0,2}my car 

this regex demo См (который будет использоваться с флагом re.IGNORECASE).См Python demo:

import re 
txt = 'Chevy is my car and Rusty is my horse.\nMy car is very pretty my dog is red.' 
print(re.findall(r'(?:\S+[ \t]+){0,2}my car', txt, re.I)) 

Детали:

  • (?:\S+[ \t]+){0,2} - от 0 до 2 последовательности 1+, не являющихся непечатаемых с последующим 1+ пространства или символов табуляции (вы также можете заменить его [^\S\r\n], чтобы соответствовать любое горизонтальное пространство или \s, если вы также планируете сопоставлять строки).
  • my car - буквальный текст my car.
+0

Но осторожно, в регулярном выражении '[^ |]' the caret * does * имеет особое значение, хотя и другое, - это делает класс символов совпадающим с любым символом, который * не * присутствует в классе (например, ничего, кроме символ '|' в этом случае) ... –

+0

@TimPietzcker: Да, эта часть должна быть описана в [SO documenation] (http://stackoverflow.com/documentation/regex/1757/character-classes) , Тем не менее, такого объяснения пока нет. –

+0

Мне было интересно спросить, следует ли вам расширять то, почему '\ b'" между словами ведет себя не так, как ожидалось, но поскольку он, кажется, добавляется OP как часть «случайных кодов ввода до тех пор, пока он не работает», I 'll forego it ... – usr2564301

Смежные вопросы