Les expressions régulières du module re prennent-elles en charge les limites de mots (\ b)?

100

Tout en essayant d'en savoir un peu plus sur les expressions régulières, un didacticiel vous a suggéré d'utiliser \bpour faire correspondre une limite de mot. Cependant, l'extrait de code suivant dans l'interpréteur Python ne fonctionne pas comme prévu:

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

Cela aurait dû être un objet de correspondance si quelque chose correspondait, mais c'est le cas None.

L' \bexpression n'est-elle pas prise en charge dans Python ou est-ce que je l'utilise mal?

DC
la source
31
Cela fonctionnera:re.search(r"\btwo\b", x)
Bolo
5
Pourquoi n'utilisez-vous pas des chaînes "brutes"? r"\btwo\b"?
S.Lott
3
Les gens sont souvent confus au sujet \b.
tchrist
Oui, Python le fait, vous avez juste besoin d'une chaîne brute r'\b'pour que le caractère soit échappé. (ou bien double-échapper \\b, ce qui est yukky)
smci

Réponses:

85

Pourquoi tu n'essaies pas

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

Production:

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

J'ai également oublié de mentionner que vous devriez utiliser des chaînes brutes dans votre code

>>> x = 'one two three'
>>> y = re.search(r"\btwo\b", x)
>>> y
<_sre.SRE_Match object at 0x100418a58>
>>> 
pyfunc
la source
Intéressant, merci pour l'exemple de travail. Savez-vous pourquoi la méthode que j'ai choisie ne fonctionne pas? Les deux approches devraient être les mêmes, sauf que dans votre approche, vous ne compilez qu'une seule fois.
DC
1
@darren: Voir mon dernier exemple qui améliore simplement ce que vous avez fait. J'ai fourni des chaînes brutes à rechercher.
pyfunc
1
ahh après la vôtre et celle de Bolo, c'était parce que je n'utilisais pas de chaîne brute. Merci!
DC
9
-1: vers l'arrière. Les chaînes brutes doivent être les premières. L'autre tâche de construire une expression ré avec %substitution de chaîne est une mauvaise tangente, sans rapport avec cette question particulière.
S.Lott
2
Mauvaise réponse. Le code fonctionne, mais il n'y a aucune explication.
Aran-Fey
88

Cela fonctionnera: re.search(r"\btwo\b", x)

Lorsque vous écrivez "\b"en Python, il est un seul caractère: "\x08". Soit échappez à la barre oblique inverse comme ceci:

"\\b"

ou écrivez une chaîne brute comme celle-ci:

r"\b"
Bolo
la source
4
Cela m'a vraiment aidé ... J'avais du mal avec une expression régulière de type pyspark et je n'arrivais pas à comprendre pourquoi \ b (limite de mot) ne fonctionnait pas. Merci
jb1t
17

Juste pour expliquer explicitement pourquoi re.search("\btwo\b", x) ne fonctionne pas, c'est parce que \bdans une chaîne Python est un raccourci pour un caractère de retour arrière.

print("foo\bbar")
fobar

Le motif "\btwo\b"recherche donc un retour arrière, suivi de two, suivi d'un autre retour arrière, que la chaîne que vous recherchez dans ( x = 'one two three') n'a pas.

Pour permettre re.search(ou compile) d'interpréter la séquence \bcomme une limite de mot, échappez aux contre-obliques ( "\\btwo\\b") ou utilisez une chaîne brute pour créer votre motif ( r"\btwo\b").

Bill le lézard
la source
10

Documentation Python

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

\ b

Correspond à la chaîne vide, mais uniquement au début ou à la fin d'un mot. Un mot est défini comme une séquence de caractères alphanumériques ou de soulignement, de sorte que la fin d'un mot est indiquée par un espace ou un caractère non alphanumérique et non souligné. Notez que formellement, \ b est défini comme la limite entre un \ w et un \ W caractère (ou vice versa), ou entre \ w et le début / la fin de la chaîne, donc le jeu précis de caractères réputés alphanumériques dépend sur les valeurs des drapeaux UNICODE et LOCALE. Par exemple, r '\ bfoo \ b' correspond à 'foo', 'foo.', '(Foo)', 'bar foo baz' mais pas à 'foobar' ou 'foo3'. À l'intérieur d'une plage de caractères, \ b représente le caractère de retour arrière, pour la compatibilité avec les chaînes littérales de Python.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source