Czy wyrażenia regularne z modułu re obsługują granice słów (\ b)?


100

Próbując dowiedzieć się więcej o wyrażeniach regularnych, w samouczku zasugerowano, że możesz użyć znaku, \baby dopasować granicę słowa. Jednak następujący fragment kodu w interpreterze języka Python nie działa zgodnie z oczekiwaniami:

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

Powinien być obiektem dopasowania, jeśli cokolwiek zostało dopasowane, ale tak jest None.

Czy \bwyrażenie nie jest obsługiwane w Pythonie, czy też używam go źle?


31
To zadziała:re.search(r"\btwo\b", x)
Bolo

5
Dlaczego nie używasz „surowych” ciągów? r"\btwo\b"?
S.Lott

3
Ludzie są często mylone temat \b.
tchrist

Tak, Python tak, potrzebujesz tylko nieprzetworzonego łańcucha, r'\b'aby znak został pominięty. (albo podwójna ucieczka \\b, co jest dziwne)
smci

Odpowiedzi:


85

Dlaczego nie spróbujesz

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

Wynik:

>>> 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>

Zapomniałem również wspomnieć, że powinieneś używać nieprzetworzonych ciągów w kodzie

>>> x = 'one two three'
>>> y = re.search(r"\btwo\b", x)
>>> y
<_sre.SRE_Match object at 0x100418a58>
>>> 

Ciekawe, dzięki za przykład roboczy. Czy wiesz, dlaczego wybrana przeze mnie metoda nie działa? Te dwa podejścia powinny być takie same, z wyjątkiem tego, że w Twoim podejściu kompilujesz tylko raz.
DC

1
@darren: Zobacz mój ostatni przykład, który po prostu ulepsza to, co zrobiłeś. Podałem nieprzetworzone ciągi do wyszukiwania.
pyfunc

1
ach, po twojej i sugestii Bolo, to dlatego, że nie użyłem surowego sznurka. Dzięki!
DC

9
-1: do tyłu. Surowe łańcuchy powinny być pierwsze. Inną sprawą związaną z budowaniem wyrażenia zwrotnego z %podstawieniem łańcucha jest zła tangens, nieistotna dla tego konkretnego pytania.
S.Lott

2
Zła odpowiedź. Kod działa, ale nie ma żadnego wyjaśnienia.
Aran-Fey

88

To zadziała: re.search(r"\btwo\b", x)

Gdy piszesz "\b"w Pythonie, jest to pojedynczy znak: "\x08". Albo uniknij odwrotnego ukośnika w ten sposób:

"\\b"

lub napisz nieprzetworzony ciąg w ten sposób:

r"\b"

4
To naprawdę mi pomogło ... Walczyłem z wyrażeniem regularnym podobnym do pysparka r i nie mogłem zrozumieć, dlaczego \ b (granica słowa) nie działa. Dzięki
jb1t

17

Aby wyraźnie wyjaśnić, dlaczego re.search("\btwo\b", x) nie działa, dzieje się tak, ponieważ \bw ciągu Pythona jest skrótem dla znaku cofania.

print("foo\bbar")
fobar

Tak więc wzorzec "\btwo\b"szuka znaku cofnięcia, po którym twonastępuje kolejny znak cofania, którego nie ma w ciągu szukanym w ( x = 'one two three').

Aby umożliwić re.search(lub compile) zinterpretowanie sekwencji \bjako granicy wyrazu, należy uciec przed ukośnikami odwrotnymi ( "\\btwo\\b") lub użyć nieprzetworzonego ciągu znaków do utworzenia wzorca ( r"\btwo\b").


10

Dokumentacja Pythona

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

\b

Dopasowuje pusty ciąg, ale tylko na początku lub na końcu słowa. Słowo jest definiowane jako sekwencja znaków alfanumerycznych lub znaków podkreślenia, więc koniec słowa jest oznaczony białą spacją lub niealfanumerycznym znakiem bez podkreślenia. Zauważ, że formalnie \ b jest definiowane jako granica między a \ w a \ W (lub odwrotnie) lub między \ w a początkiem / końcem ciągu, więc dokładny zestaw znaków uznawanych za alfanumeryczne zależy na wartości flag UNICODE i LOCALE. Na przykład r '\ bfoo \ b' pasuje do „foo”, „foo.”, „(Foo)”, „bar foo baz”, ale nie do „foobar” ani „foo3”. W zakresie znaków \ ​​b reprezentuje znak cofania, aby zapewnić zgodność z literałami łańcuchowymi Pythona.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.