Поддерживают ли регулярные выражения из модуля re границы слов (\ b)?

100

Пытаясь узнать немного больше о регулярных выражениях, в руководстве было предложено использовать \bдля сопоставления границы слова. Однако следующий фрагмент в интерпретаторе Python не работает должным образом:

>>> x = 'one two three'
>>> y = re.search("\btwo\b", x)

Это должен был быть объект соответствия, если что-то было найдено, но это так None.

Это \bвыражение не поддерживается в Python или я использую его неправильно?

ОКРУГ КОЛУМБИЯ
источник
31
Это сработает:re.search(r"\btwo\b", x)
Боло
5
Почему вы не используете «сырые» строки? r"\btwo\b"?
S.Lott
3
Люди часто путают о \b.
tchrist
Да, Python делает, вам просто нужна необработанная строка, r'\b'чтобы символ был экранирован. (или дважды экранируйте его \\b, что противно)
smci

Ответы:

85

Почему бы тебе не попробовать

word = 'two'
re.compile(r'\b%s\b' % word, re.I)

Вывод:

>>> word = 'two'
>>> k = re.compile(r'\b%s\b' % word, re.I)
>>> x = 'one two three'
>>> y = k.search( x)
>>> y
<_sre.SRE_Match object at 0x100418850>

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

>>> x = 'one two three'
>>> y = re.search(r"\btwo\b", x)
>>> y
<_sre.SRE_Match object at 0x100418a58>
>>> 
pyfunc
источник
Интересно, спасибо за рабочий пример. Есть ли у вас какое-нибудь представление о том, почему выбранный мной метод не работает? Два подхода должны быть одинаковыми, за исключением того, что в вашем подходе вы компилируете только один раз.
DC
1
@darren: Посмотрите мой последний пример, который просто улучшает то, что вы сделали. Я предоставил для поиска необработанные строки.
pyfunc
1
ах после вашего предложения и предложения Боло, это произошло потому, что я не использовал необработанную строку. Спасибо!
DC
9
-1: Назад. Необработанные строки должны быть первыми. Другой способ построения выражения re с %подстановкой строк - плохой касательный, не имеющий отношения к этому конкретному вопросу.
S.Lott
2
Плохой ответ. Код работает, но никаких объяснений нет.
Aran-Fey
88

Это будет работать: re.search(r"\btwo\b", x)

Когда вы пишете "\b"в Python, это один символ: "\x08". Либо избегайте обратной косой черты следующим образом:

"\\b"

или напишите необработанную строку следующим образом:

r"\b"
Боло
источник
4
Это действительно помогло мне ... Я боролся с регулярным выражением pyspark rlike и не мог понять, почему \ b (граница слова) не работает. Спасибо
jb1t
17

Просто чтобы явно объяснить, почему re.search("\btwo\b", x) не работает, это потому, что \bв строке Python есть сокращение для символа возврата.

print("foo\bbar")
fobar

Таким образом, шаблон "\btwo\b"ищет пробел, за которым twoследует другой пробел, которого нет в строке, которую вы ищете в ( x = 'one two three').

Чтобы разрешить re.search(или compile) интерпретировать последовательность \bкак границу слова, либо избегайте обратной косой черты ( "\\btwo\\b"), либо используйте необработанную строку для создания шаблона ( r"\btwo\b").

Билл Ящерица
источник
10

Документация Python

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

\ b

Соответствует пустой строке, но только в начале или в конце слова. Слово определяется как последовательность буквенно-цифровых символов или символов подчеркивания, поэтому конец слова обозначается пробелом или не буквенно-цифровым символом без подчеркивания. Обратите внимание, что формально \ b определяется как граница между символом \ w и \ W (или наоборот) или между \ w и началом / концом строки, поэтому точный набор символов, который считается буквенно-цифровым, зависит на значениях флагов UNICODE и LOCALE. Например, r '\ bfoo \ b' соответствует 'foo', 'foo.', '(Foo)', 'bar foo baz', но не 'foobar' или 'foo3'. Внутри диапазона символов \ b представляет символ обратного пробела для совместимости со строковыми литералами Python.

Чиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник