Regex corresponde apenas a palavras inteiras

92

Eu tenho uma expressão regex que estou usando para localizar todas as palavras em um determinado bloco de conteúdo, sem distinção entre maiúsculas e minúsculas, que estão contidas em um glossário armazenado em um banco de dados. Aqui está meu padrão:

/($word)/i

O problema é que, se eu usar /(Foo)/ipalavras como Foodobter correspondência. Deve haver um espaço em branco ou um limite de palavra em ambos os lados da palavra.

Como posso modificar minha expressão para corresponder apenas à palavra Fooquando é uma palavra no início, meio ou final de uma frase?

Aaron
fonte

Respostas:

126

Use limites de palavras:

/\b($word)\b/i

Ou se você estiver procurando por "SPECTRE" como no exemplo de Sinan Ünür:

/(?:\W|^)(\Q$word\E)(?:\W|$)/i
Richard Simões
fonte
1
Eu estava digitando a versão longa desta resposta quando você postou. :)
ZombieSheep
@RichardSimoes \b(<|>=)\bnão corresponde>=
alhelal
@RichardSimoes e \b[-|+][0-9]+\bjogo +10em 43E+10. Ambos eu não quero.
alhelal
e se eu quiser pesquisar uma palavra que não está anexada ou não está contida em nenhuma outra palavra. então essa lógica não funcionará
Prasanna Sasne
Como alguém obteria os operadores de comparação matemática> = e <=?
AntonSack
52

Para corresponder a qualquer palavra inteira, você usaria o padrão (\w+)

Supondo que você esteja usando PCRE ou algo semelhante:

insira a descrição da imagem aqui

Captura de tela acima tirada deste exemplo ao vivo: http://regex101.com/r/cU5lC2

Combinando qualquer palavra inteira na linha de comando com (\w+)

Eu vou estar usando o shell interativo phpsh no Ubuntu 12.10 para demonstrar a motor PCRE regex através do método conhecido como preg_match

Inicie o phpsh, coloque algum conteúdo em uma variável, combine na palavra.

el@apollo:~/foo$ phpsh

php> $content1 = 'badger'
php> $content2 = '1234'
php> $content3 = '$%^&'

php> echo preg_match('(\w+)', $content1);
1

php> echo preg_match('(\w+)', $content2);
1

php> echo preg_match('(\w+)', $content3);
0

O método preg_match utilizado o motor PCRE dentro da linguagem PHP para analisar variáveis: $content1, $content2e $content3com o (\w)+padrão.

$ content1 e $ content2 contêm pelo menos uma palavra, $ content3 não.

Combine uma série de palavras literais na linha de comando com (dart|fart)

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(dart|fart)', $gun1);
1

php> echo preg_match('(dart|fart)', $gun2);
1

php> echo preg_match('(dart|fart)', $gun3);
1

php> echo preg_match('(dart|fart)', $gun4);
0

as variáveis ​​gun1 e gun2 contêm o string dart ou fart. gun4 não. No entanto, pode ser um problema procurar por fartcorrespondências de palavrasfarty . Para corrigir isso, aplique limites de palavras no regex.

Combine palavras literais na linha de comando com limites de palavras.

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(\bdart\b|\bfart\b)', $gun1);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun2);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun3);
0

php> echo preg_match('(\bdart\b|\bfart\b)', $gun4);
0

Portanto, é o mesmo que o exemplo anterior, exceto que a palavra fartcom um \blimite de palavra não existe no conteúdo: farty.

Eric Leschinski
fonte
am, pm não são palavras?
servo de
Se você deseja forçar am e pm a serem palavras (não são, são siglas), adicione um ponto final como um caractere de palavra para seu mecanismo de regex. Para você, parece que você definiu o período como não sendo um caractere de palavra, portanto, as palavras de regex não serão uma a uma e para a definição padrão de "palavra" que você aprendeu em seu Dicionário europeu para seu europeu híbrido idioma (ou qualquer outro idioma para esse assunto).
Eric Leschinski
8

O uso \bpode produzir resultados surpreendentes. Seria melhor você descobrir o que separa uma palavra de sua definição e incorporar essa informação em seu padrão.

#!/usr/bin/perl

use strict; use warnings;

use re 'debug';

my $str = 'S.P.E.C.T.R.E. (Special Executive for Counter-intelligence,
Terrorism, Revenge and Extortion) is a fictional global terrorist
organisation';

my $word = 'S.P.E.C.T.R.E.';

if ( $str =~ /\b(\Q$word\E)\b/ ) {
    print $1, "\n";
}

Resultado:

Compilando REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Programa final:
   1: LIMITADO (2)
   2: ABRIR 1 (4)
   4: EXATO (9)
   9: FECHAR 1 (11)
  11: LIMITE (12)
  12: END (0)
ancorado "SPECTER" em 0 (verificando ancorado) stclass BOUND minlen 14
Estimando o início da partida em sv para REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contra "SP
.ECTRE (Executivo Especial para Contra-inteligência, "...
Substrução ancorada "SPECTER" encontrada no deslocamento 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
Não contradiz STCLASS ...
Adivinhada: correspondência no deslocamento 0
Corresponder REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contra "SPECTER (Special Exec
utive para contra-inteligência, "...
   0 | 1: LIMITADO (2)
   0 | 2: ABRIR 1 (4)
   0 | 4: EXATO (9)
  14 9: FECHAR 1 (11)
  14 11: LIMITE (12)
                                  falhou ...
A partida falhou
Liberando REx: "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Sinan Ünür
fonte
1
Acho que uma palavra normalmente será uma palavra, mas é um ponto interessante.
Richard Simões
1

use limites de palavras \ b,

O seguinte (usando quatro escapes) funciona em meu ambiente: Mac, safari versão 10.0.3 (12602.4.8)

var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)
X. L
fonte
1

Para aqueles que desejam validar um Enum em seu código, você pode seguir o guia

No Regex World você pode usar ^para iniciar uma string e $finalizá-la. Usá-los em combinação com |pode ser o que você deseja:

^(Male)$|^(Female)$

Ele retornará verdadeiro apenas para Maleou Femalecaso.

MohamadrezaRahimianGolkhandani
fonte
^e $corresponder ao início (respectivamente ao final) de uma linha, portanto, seu exemplo corresponderia apenas se essas fossem as únicas palavras na linha.
agendado em
e é exatamente isso que eu quero quando quero validar um enum! qual é o problema?
MohamadrezaRahimianGolkhandani
0

Se você estiver fazendo isso no Notepad ++

[\w]+ 

Fornece a palavra inteira e você pode adicionar parênteses para obtê-la como um grupo. Exemplo: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Eu gostaria de mudarLeakyReLU para sua própria linha como um comentário e substituir a ativação atual. No notepad ++, isso pode ser feito usando o seguinte comando find:

([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)

e o comando de substituição torna-se:

\1\2'relu'\4 \n    # \1 = LeakyReLU\(alpha=a\)\(\1\)

Os espaços são para manter a formatação correta no meu código. :)

JTIM
fonte
-1

Pegue todas as "palavras" em uma string

/([^\s]+)/g

Basicamente ^/ssignifica quebrar em espaços (ou combinar grupos de não espaços).
Não se esqueça de gpara Greedy

gdibble
fonte