As expressões regulares do módulo re-suportam limites de palavras (\ b)?

100

Ao tentar aprender um pouco mais sobre as expressões regulares, um tutorial sugeriu que você pode usar o \bpara corresponder ao limite de uma palavra. No entanto, o seguinte snippet no interpretador Python não funciona conforme o esperado:

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

Deveria ter sido um objeto de correspondência se algo fosse correspondido, mas é None.

A \bexpressão não é compatível com Python ou estou usando incorretamente?

DC
fonte
31
Isso vai funcionar:re.search(r"\btwo\b", x)
Bolo,
5
Por que você não está usando strings "brutas"? r"\btwo\b"?
S.Lott,
3
As pessoas muitas vezes ficam confusas sobre \b.
tchrist de
Sim, Python precisa, você só precisa da string bruta r'\b'para que o caractere seja escapado. (ou então \\b

Respostas:

85

Por que você não tenta

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

Resultado:

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

Também esqueci de mencionar que você deve usar strings brutas em seu código

>>> x = 'one two three'
>>> y = re.search(r"\btwo\b", x)
>>> y
<_sre.SRE_Match object at 0x100418a58>
>>> 
pyfunc
fonte
Interessante, obrigado pelo exemplo de trabalho. Você tem alguma ideia de por que o método que escolhi não funciona? As duas abordagens devem ser iguais, exceto que em sua abordagem você está compilando apenas uma vez.
DC,
1
@darren: Veja meu último exemplo que apenas melhora o que você fez. Eu forneci strings brutas para pesquisar.
pyfunc,
1
ahh depois da sua sugestão e do Bolo, foi porque eu não estava usando um barbante cru. Obrigado!
DC,
9
-1: Para trás. As strings brutas devem vir primeiro. O outro negócio de construir uma reexpressão com %substituição de string é uma tangente ruim, irrelevante para esta questão em particular.
S.Lott,
2
Resposta ruim. O código funciona, mas não há explicação alguma.
Aran-Fey
88

Isso vai funcionar: re.search(r"\btwo\b", x)

Quando você escreve "\b"em Python, é um único caractere: "\x08". Ou escape a barra invertida desta forma:

"\\b"

ou escreva uma string bruta como esta:

r"\b"
Bolo
fonte
4
Isso realmente me ajudou ... Eu estava lutando com uma expressão regular pyspark rlike e não conseguia descobrir por que o \ b (limite de palavra) não estava funcionando. Obrigado
jb1t
17

Apenas para explicar explicitamente por re.search("\btwo\b", x) que não funciona, é porque \bem uma string Python é uma abreviação para um caractere de retrocesso.

print("foo\bbar")
fobar

Portanto, o padrão "\btwo\b"está procurando um backspace, seguido por two, seguido por outro backspace, que a string que você está procurando em ( x = 'one two three') não tem.

Para permitir re.search(ou compile) interpretar a sequência \bcomo um limite de palavra, escape das barras invertidas ( "\\btwo\\b") ou use uma string bruta para criar seu padrão ( r"\btwo\b").

Bill the Lizard
fonte
10

Documentação Python

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

\ b

Corresponde à string vazia, mas apenas no início ou no final de uma palavra. Uma palavra é definida como uma sequência de caracteres alfanuméricos ou sublinhados, portanto, o final de uma palavra é indicado por um espaço em branco ou um caractere não alfanumérico e não sublinhado. Observe que, formalmente, \ b é definido como o limite entre um caractere \ w e a \ W (ou vice-versa), ou entre \ w e o início / fim da string, portanto, o conjunto preciso de caracteres considerados alfanuméricos depende nos valores dos sinalizadores UNICODE e LOCALE. Por exemplo, r '\ bfoo \ b' corresponde a 'foo', 'foo.', '(Foo)', 'bar foo baz', mas não a 'foobar' ou 'foo3'. Dentro de um intervalo de caracteres, \ b representa o caractere backspace, para compatibilidade com os literais de string do Python.

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