Чи регулярні вирази з модуля 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>
>>> 

Цікаво, дякую за робочий приклад. Чи маєте ви якесь розуміння, чому обраний нами метод не працює? Два підходи повинні бути однаковими, за винятком того, що ви використовуєте лише один раз.
DC

1
@darren: Дивіться мій останній приклад, який просто покращує те, що ви робили. Я надав сировинні рядки для пошуку.
pyfunc

1
Аа, після вашої та пропозиції Боло, це було тому, що я не використовував сирий рядок. Дякую!
DC

9
-1: назад. Сирі рядки повинні бути першими. Інший бізнес зі створення повторного вираження з %підстановкою рядків є поганою дотичною, не має значення для цього конкретного питання.
S.Lott

2
Погана відповідь. Код працює, але пояснення ні до чого.
Аран-Фей

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.