2008-10-16 58 views
6

¿Qué debo usar para buscar varias palabras en una cadena? Me gustaría que la operación lógica sea Y para que todas las palabras estén en la cadena en alguna parte. Tengo un montón de párrafos sin sentido y un solo párrafo en inglés, y me gustaría limitarlo especificando un par de palabras comunes como "the" y "and", pero me gustaría que coincidiera con todas las palabras que especifico.Regex búsqueda de palabras múltiples

Respuesta

2

Tal vez usando un language recognition chart reconocer Inglés funcionaría. Algunas pruebas rápidas parecen funcionar (esto supone párrafos separados solo por líneas nuevas).

La expresión regular coincidirá con una de esas condiciones ... \ bword \ b es la palabra separada por límites word \ b es una palabra que termina y la palabra justa coincidirá en cualquier lugar del párrafo que se va a emparejar.

my @paragraphs = split(/\n/,$text); 
for my $p (@paragraphs) { 
    if ($p =~ m/\bthe\b|\band\b|\ban\b|\bin\b|\bon\b|\bthat\b|\bis\b|\bare\b|th|sh|ough|augh|ing\b|tion\b|ed\b|age\b|’s\b|’ve\b|n’t\b|’d\b/) { 
     print "Probable english\n$p\n"; 
    } 
} 
+0

No recomendaría 'on' para detectar inglés. Significa 'él' en muchos idiomas eslavos (como estoy seguro que Vinko sabe;) –

+0

url se ha movido: http://en.wikipedia.org/wiki/Wikipedia:Language_recognition_chart#English –

0

Asumiendo PCRE (Perl regexes), no estoy seguro de que pueda hacerlo con facilidad. La operación AND es una concatenación de expresiones regulares, pero desea poder permutar el orden en que aparecen las palabras sin tener que generar formalmente la permutación. Para N palabras, cuando N = 2, es soportable; con N = 3, apenas está bien; con N> 3, es poco probable que sea aceptable. Por lo tanto, la solución iterativa simple (N regexes, una para cada palabra e iterar para garantizar que cada uno esté satisfecho) parece ser la mejor opción para mí.

+0

¿Por qué las N cosas tienen que ser expresiones regulares sin embargo? Podría simplemente usar "índice" aquí. –

+1

\ b (foo | bar | baz) \ b. * \ B (?! \ 1) (foo | bar | baz) \ b. * \ B (?! \ 1) (?! \ 2) (foo | bar | baz) \ b debería manejar las permutaciones mediante el uso de referencias anteriores y lookahead negativo para evitar emparejar una palabra dos veces. Todavía es propiamente malvado, pero al menos la longitud del patrón no es O (N!) – stevemegson

+0

@BKB: No estoy seguro de lo que quiere decir con el uso de un índice. –

2

En primer lugar, no estoy seguro de lo que intentas devolver ... ¿la frase completa? ¿Las palabras entre tus dos palabras dadas?

Algo así como:

\b(word1|word2)\b(\w+\b)*(word1|word2)\b(\w+\b)*\. 

(donde \b es el límite de palabra en su idioma) coincidiría con una oración completa que contenía ninguna de las dos palabras o ambos ..

que probablemente necesita para que sea sensible a mayúsculas de manera que si aparece al comienzo de la frase que sigue coincidirá

+0

¿Eso no coincide con una oración que contiene dos palabras, ya sea word1 seguido de word2, o word2 seguido de word1 (como se desee), o word1 seguido de word1, o word2 seguido de word2 (como no deseado)? Ese fue el tipo de problema que encontré cuando trato de responder. –

2

AND como concatenación

^(?=.*?\b(?:word1)\b)(?=.*?\b(?:word2)\b)(?=.*?\b(?:word3)\b) 

OR como alternancia

^(?=.*?\b(?:word1|word2|word3)\b 
^(?=.*?\b(?:word1)\b)|^(?=.*?\b(?:word2)\b)|^(?=.*?\b(?:word3)\b) 
11

Las expresiones regulares compatibles con una condición "lookaround" que le permite buscar un término dentro de una cadena y luego se olvida la ubicación del resultado; comenzando al principio de la cadena para el siguiente término de búsqueda. Esto permitirá buscar una cadena para un grupo de palabras en cualquier orden.

La expresión regular para este es:

^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b) 

Dónde \b es un límite de palabra y la ?= es el modificador Lookaround.

Si tiene un número variable de palabras que desea buscar, deberá compilar esta cadena de expresión regular con un bucle; simplemente ajuste cada palabra en la sintaxis de búsqueda y añádala a la expresión.

+0

Exactamente lo que necesitaba. Tenga en cuenta que falta un par de asteriscos arriba. Cada sección debe ser '(? =. * \ Bword \ b)' – Tamlyn

+0

Los asteriscos estaban allí, pero estaban siendo tratados como marcas. Lo arreglé aplicando el formato del código. –

Cuestiones relacionadas