Regex coincide solo con palabras completas

90

Tengo una expresión regex que estoy usando para encontrar todas las palabras en un bloque de contenido dado, sin distinción entre mayúsculas y minúsculas, que están contenidas en un glosario almacenado en una base de datos. Aquí está mi patrón:

/($word)/i

El problema es que si utilizo /(Foo)/ipalabras como Foodemparejar. Debe haber espacios en blanco o un límite de palabra a ambos lados de la palabra.

¿Cómo puedo modificar mi expresión para que coincida solo con la palabra Foocuando es una palabra al principio, en medio o al final de una oración?

Aaron
fuente

Respuestas:

120

Utilice límites de palabras:

/\b($word)\b/i

O si está buscando "SPECTRE" como en el ejemplo de Sinan Ünür:

/(?:\W|^)(\Q$word\E)(?:\W|$)/i
Richard Simões
fuente
1
Estaba escribiendo la versión a mano larga de esta respuesta cuando publicaste. :)
ZombieSheep
@RichardSimoes \b(<|>=)\bno coincide>=
alhelal
@RichardSimoes y \b[-|+][0-9]+\bpartido +10en 43E+10. Ambos no los quiero.
alhelal
¿Qué pasa si quiero buscar una palabra que no esté adjunta o que no esté contenida en ninguna otra palabra? entonces esta lógica no funcionará
Prasanna Sasne
¿Cómo obtendría alguien los operadores de comparación matemática> = y <=?
AntonSack
50

Para hacer coincidir cualquier palabra completa, usaría el patrón (\w+)

Suponiendo que está usando PCRE o algo similar:

ingrese la descripción de la imagen aquí

Captura de pantalla anterior tomada de este ejemplo en vivo: http://regex101.com/r/cU5lC2

Hacer coincidir cualquier palabra completa en la línea de comandos con (\w+)

Voy a estar utilizando el shell interactivo phpsh en Ubuntu 12.10 para demostrar el motor PCRE expresión regular a través del método conocido como preg_match

Inicie phpsh, ponga algo de contenido en una variable, coincida con la palabra.

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

El método utiliza el motor preg_match PCRE dentro del lenguaje PHP para analizar las variables: $content1, $content2y $content3con el (\w)+patrón.

$ content1 y $ content2 contienen al menos una palabra, $ content3 no.

Haga coincidir un número de palabras literales en la línea de comandos con (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

Las variables gun1 y gun2 contienen la cadena dart o fart. gun4 no lo hace. Sin embargo, puede ser un problema buscar fartcoincidencias de palabras farty. Para solucionar este problema, aplique límites de palabras en expresiones regulares.

Haga coincidir palabras literales en la línea de comandos con límites de palabras.

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

Por lo que es lo mismo que el ejemplo anterior, excepto que la palabra fartcon un \blímite de palabra no existe en el contenido: farty.

Eric Leschinski
fuente
am, pm no son palabras?
minion
Si desea forzar que am y pm sean palabras (no lo son, son siglas), agregue un punto como carácter de palabra para su motor de expresiones regulares. Para usted, parece que ha establecido el punto como un carácter que no es una palabra, por lo tanto, las palabras regex no serán una a una ni una para la definición estándar de "palabra" que le enseñaron en su Diccionario europeo para su europeo híbrido. idioma (o cualquier otro idioma para el caso).
Eric Leschinski
8

El uso \bpuede producir resultados sorprendentes. Sería mejor averiguar qué separa una palabra de su definición e incorporar esa información en su patrón.

#!/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";
}

Salida:

Compilando REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Programa final:
   1: VINCULADO (2)
   2: ABIERTO1 (4)
   4: EXACTO (9)
   9: CERRAR1 (11)
  11: ATADO (12)
  12: FIN (0)
anclado "SPECTRE" en 0 (comprobación anclado) stclass BOUND minlen 14
Adivinando el inicio del partido en sv para REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contra "SP
.ECTRE (Ejecutivo Especial de Contrainteligencia, "...
Se encontró substr anclado "SPECTRE" en el desplazamiento 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
No contradice STCLASS ...
Adivinado: coincidencia en offset 0
Coincidencia de REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" contra "SPECTRE (Ejec
utivo para la contrainteligencia, "...
   0 | 1: VINCULADO (2)
   0 | 2: ABIERTO1 (4)
   0 | 4: EXACTO (9)
  14 | 9: CERRAR1 (11)
  14 | 11: ATADO (12)
                                  ha fallado...
Partido fallido
Liberando REx: "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Sinan Ünür
fuente
1
Creo que una palabra suele ser una palabra, pero un punto interesante.
Richard Simões
1

usar límites de palabras \ b,

Lo siguiente (usando cuatro escapes) funciona en mi entorno: Mac, safari Versión 10.0.3 (12602.4.8)

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

Para aquellos que quieran validar una enumeración en su código, pueden seguir la guía

En Regex World se puede utilizar ^para iniciar una cadena y $finalizarla. Usarlos en combinación con |podría ser lo que quieras:

^(Male)$|^(Female)$

Devolverá verdadero solo para Maleo Femalecaso.

MohamadrezaRahimianGolkhandani
fuente
^y $coincidir con el comienzo (respectivamente el final) de una línea, por lo tanto, su ejemplo coincidiría solo si esas son las únicas palabras en la línea.
gented
¡y esto es exactamente lo que quiero cuando quiero validar una enumeración! ¿Cuál es el problema?
MohamadrezaRahimianGolkhandani
0

Si lo está haciendo en Notepad ++

[\w]+ 

Le daría la palabra completa y puede agregar paréntesis para obtenerla como grupo. Ejemplo: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Me gustaría pasar LeakyReLUa su propia línea como comentario y reemplazar la activación actual. En notepad ++, esto se puede hacer usando el siguiente comando de búsqueda:

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

y el comando de reemplazo se convierte en:

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

Los espacios son para mantener el formato correcto en mi código. :)

JTIM
fuente
-1

Obtener todas las "palabras" en una cadena

/([^\s]+)/g

Básicamente ^/ssignifica romper en espacios (o combinar grupos de no espacios)
No te olvides gde Greedy

gdibble
fuente