Regex: especifique "espaço ou início da sequência" e "espaço ou final da sequência"

127

Imagine que você está tentando padronizar a correspondência "stackoverflow".

Você deseja o seguinte:

 this is stackoverflow and it rocks [MATCH]

 stackoverflow is the best [MATCH]

 i love stackoverflow [MATCH]

 typostackoverflow rules [NO MATCH]

 i love stackoverflowtypo [NO MATCH]

Eu sei como analisar o stackoverflow se houver espaços nos dois sites usando:

/\s(stackoverflow)\s/

O mesmo se no início ou no final de uma string:

/^(stackoverflow)\s/

/\s(stackoverflow)$/

Mas como você especifica "espaço ou final de sequência" e "espaço ou início de sequência" usando uma expressão regular?

anônimo-um
fonte

Respostas:

172

Você pode usar qualquer um dos seguintes:

\b      #A word break and will work for both spaces and end of lines.
(^|\s)  #the | means or. () is a capturing group. 


/\b(stackoverflow)\b/

Além disso, se você não quiser incluir o espaço em sua partida, use lookbehind / aheads.

(?<=\s|^)         #to look behind the match
(stackoverflow)   #the string you want. () optional
(?=\s|$)          #to look ahead.
Jacob Eggers
fonte
8
\bé uma afirmação de largura zero; nunca consome caracteres. Não há necessidade de envolvê-lo em uma visão geral.
Alan Moore
2
Observe que na maioria das implementações de regexp, \bé apenas padrão ASCII , ou seja, não há suporte a unicode. Se você precisar corresponder palavras unicode, não terá outra opção senão usá-las: stackoverflow.com/a/6713327/1329367
Mahn
4
A maneira mais fácil de excluir a seleção do grupo da partida é(?:^|\s)
user2426679
7
para python, substitua (?<=\s|^)por (?:(?<=\s)|(?<=^)). Caso contrário, você começaerror: look-behind requires fixed-width pattern
user2426679
4
Eles \bconsiderariam outros caracteres - como " ." como quebra-palavras, enquanto o solicitante disse especificamente "espaço". A solução do @ gordy parece melhor.
21417 Mikhail T. #
65

(^|\s)corresponderia ao espaço ou início da sequência e ($|\s)ao espaço ou final da sequência. Juntos, é:

(^|\s)stackoverflow($|\s)
gordy
fonte
4
este é o único que funciona para mim. Obrigado @gordy
robsonrosa
2
Se você usar esse padrão para substituir, lembre-se de manter os espaços no resultado substituído, substituindo pelo padrão $1string$2.
Mahn 27/01
Este é o único que funciona para mim também. Os limites das palavras nunca parecem fazer o que eu quero. Por um lado, eles combinam alguns caracteres além de espaço em branco (como traços). Isso resolveu isso para mim, porque eu estava tentando colocar $e ^entrar em uma classe de personagem, mas isso mostra que eles podem ser colocados em um grupo de padrões regular.
felwithe
17

Aqui está o que eu usaria:

 (?<!\S)stackoverflow(?!\S)

Em outras palavras, combine "stackoverflow" se não for precedido por um caractere que não seja um espaço em branco e não seguido por um caractere que não seja um espaço em branco.

Isso é mais puro (IMO) do que a abordagem "espaço ou âncora" e não pressupõe que a sequência inicie e termine com caracteres de palavra, como a \babordagem.

Alan Moore
fonte
1
boa explicação sobre por que usar isso. eu teria escolhido isso no entanto, a seqüência de caracteres sendo testada é sempre uma única linha.
anonymous-one
7

\b corresponde aos limites das palavras (sem corresponder a nenhum caractere), portanto, faça o que você deseja:

\bstackoverflow\b
Andrew Clark
fonte
Para Python que ajuda a especificar uma string bruta , por exemplomystr = r'\bstack overflow\b'
Acumenos