2008-10-28 25 views
18

Estoy tratando de escribir una expresión regular de reemplazo para rodear todas las palabras entre comillas, excepto las palabras Y, O y NO.Regex para que coincida con todas las palabras, excepto una lista dada

he intentado lo siguiente para la parte de coincidencia de la expresión:

(?i)(?<word>[a-z0-9]+)(?<!and|not|or) 

y

(?i)(?<word>[a-z0-9]+)(?!and|not|or) 

pero ni trabajo. La expresión de reemplazo es simple y actualmente rodea todas las palabras.

"${word}" 

Así

esto y esto no Eso

convierte

"Este" y "Este" no "que"

+0

¿Puede dar muestras de entrada y el resultado esperado (coincida o no)? – mohammedn

+0

(? I) (? [a-z0-9] ++) (?

Respuesta

14

Este es un poco sucio, pero funciona:

(?<!\b(?:and| or|not))\b(?!(?:and|or|not)\b) 

En la llanura Inglés, esto coincide con cualquier límite de palabra no precedida por no seguido de "y", "o", o "no". Solo coincide con palabras enteras, p. la posición después de la palabra "arena" no sería una coincidencia solo porque está precedida por "y".

El espacio delante del "o" en la aseveración "mirar atrás" de ancho cero es necesario para que sea un aspecto detrás de longitud fija. Prueba si eso ya soluciona tu problema.

EDITAR: Aplicado a la cadena "excepto las palabras Y, O y NO". como un reemplazo global con comillas simples, esto devuelve:

'except' 'the' 'words' AND, OR and NOT. 
+0

La única situación en la que esto puede fallar es cuando la cadena comienza con la palabra "o". De acuerdo, y contiene la suposición oculta de que los espacios separan tus palabras. Ambas situaciones se pueden migrar si conoce sus datos. – Tomalak

+0

Como con todos los regex, es una locura pero funciona. (? [A-Z0-9] +) ( John

+0

¿Qué se necesita "( [a- z0-9] +) "para? ¿Estás tratando de rodear tus palabras con comillas o estás tratando de sacarlas de la cuerda? – Tomalak

3

Llámame loco, pero no soy fanático de la lucha contra la expresión regular; Me limito mis patrones a las cosas simples que puedo entender, y con frecuencia trampa para el resto - por ejemplo a través de un MatchEvaluator:

string[] whitelist = new string[] { "and", "not", "or" }; 
    string input = "foo and bar or blop"; 
    string result = Regex.Replace(input, @"([a-z0-9]+)", 
     delegate(Match match) { 
      string word = match.Groups[1].Value; 
      return Array.IndexOf(whitelist, word) >= 0 
       ? word : ("\"" + word + "\""); 
     }); 

(editado para más diseño conciso)

+1

Te llamo loco. :-P – Tomalak

+1

@Tomalak: Touché –

+0

Desafortunadamente es dot net 2 por lo que no hay lambda por el momento – John

2

Basado en Tomalaks respuesta:

Esta expresión regular tiene dos problemas:

  1. (?<!) solo funciona para look-behind de longitud fija

  2. La expresión regular anterior solo miraba al final/principio de las palabras circundantes, no a la palabra completa.

(?<!\band)(?<!\bor)(?<!\bnot)\b(?!(?:and|or|not)\b)

Este expresiones regulares correcciones de ambos los problemas anteriores. Primero dividiendo la mirada atrás en tres separadas. En segundo lugar, agregando límites de palabras (\b) dentro de las búsquedas.

5

Juan,

la expresión regular en su pregunta es casi correcta. El único problema es que pones la anticipación al final de la expresión regular en lugar de al principio. Además, debe agregar límites de palabras para forzar a la expresión regular para que coincida con palabras completas. De lo contrario, coincidirá con "nd" en "y", "r" en "o", etc., porque "nd" y "r" no están en su búsqueda anticipada negativa.

\ b (i?) (Y |?! No | o) (? [A-Z0-9] +) \ b

+0

Sí, todos los demás están haciendo esto mucho más complicado de lo necesario. En particular, no hay necesidad de mirar hacia atrás negativas (o positivas, para el caso) o capturas con nombre. –

+0

Dos cosas: primero, he llegado a la conclusión de que especificando un literal '[az]' en una expresión regular en lugar de '\ pL' o' \ p {Alphabetic} 'o algunas veces' [[: alpha:]] ' casi siempre es demasiado "1960" en nuestra era posterior a los 7 bits. En segundo lugar, encuentro personas [a menudo malinterpretan lo que realmente hace]] (http://stackoverflow.com/questions/4213800/is-here-something-like-a-counter-variable-in-regular-expression-replace/4214173 # 4214173), así que últimamente he estado agregando salvedades en sus intentos cada vez que lo recomiendo. (Sí, sé que * usted * por supuesto comprende todo esto, Jan, pero muchos lectores probablemente no lo entiendan). – tchrist

0
(?!\bnot\b|\band\b|\bor\b|\b\"[^"]+\"\b)((?<=\s|\-|\(|^)[^\"\s\()]+(?=\s|\*|\)|$)) 

Yo uso esta expresión regular para encontrar todos palabras que no están entre comillas dobles o son las palabras "no" "y" o "o".

Cuestiones relacionadas