2011-08-10 28 views
10

Tengo que analizar un texto donde con es una palabra clave si no está entre corchetes. Tengo que hacer coincidir la palabra clave con. Además, debe haber límites de palabras en ambos lados de con.Regex para que coincida con una cadena NO rodeada de corchetes

Éstos son algunos ejemplos en los que con no es una palabra clave:

  • [con]
  • [con]
  • [SomeText con SomeText]
  • [SomeText con]
  • [con algún texto]

Éstos son algunos ejemplos en los que con ES palabra clave

  • con
  • ] con
  • hola con
  • hola con el mundo
  • hola [mundo] con hola
  • hola [mundo] con hello [mundo]

Cualquiera a él lp? Gracias de antemano.

Respuesta

17

Usted puede buscar la palabra with y ver que el soporte más cercano a su lado izquierdo no es un paréntesis de apertura, y que el soporte más cercano a su lado derecho no es un paréntesis de cierre:

Regex regexObj = new Regex(
    @"(?<!  # Assert that we can't match this before the current position: 
    \[  # An opening bracket 
    [^[\]]* # followed by any other characters except brackets. 
    )   # End of lookbehind. 
    \bwith\b # Match ""with"". 
    (?!  # Assert that we can't match this after the current position: 
    [^[\]]* # Any text except brackets 
    \]  # followed by a closing bracket. 
    )   # End of lookahead.", 
    RegexOptions.IgnorePatternWhitespace); 
Match matchResults = regexObj.Match(subjectString); 
while (matchResults.Success) { 
    // matched text: matchResults.Value 
    // match start: matchResults.Index 
    // match length: matchResults.Length 
    matchResults = matchResults.NextMatch(); 
} 

El las expresiones de lookaround no se detienen en los saltos de línea; si desea que cada línea se evalúe por separado, use [^[\]\r\n]* en lugar de [^[\]]*.

+0

@Tim: Su solución realmente me ayudó mucho. Ahora tengo un problema similar, solo eso, los corchetes serán reemplazados por comillas. Me refiero a '" algún texto con algún texto "' NO es una palabra clave. Traté de reemplazar los corchetes con comillas, pero no funciona. Realmente soy muy malo en Regex, necesito tu ayuda nuevamente. Gracias :) – Mohayemin

+0

@Mohaimin, mira [esta pregunta] (http://stackoverflow.com/questions/6111749/replace-whitespace-outside-quotes-using-regular-expression/6112179#6112179) que es casi una muy similar problema; simplemente reemplace la parte '[\]' en la expresión regular con '\ bwith \ b', y debería estar listo para continuar. –

+0

@Tim: Gracias, eso fue perfecto. Necesitaba solo una pequeña modificación porque tuve que combinar la cita para encontrar la expresión regular con la que diste arriba. Funcionó muy bien: D – Mohayemin

0

Te recomendamos que analices tanto los aspectos negativos como los negativos, esto te ayudará a unir tus datos sin consumir los corchetes.

3

Buena pregunta. Creo que será más fácil encontrar las coincidencias donde se aplica tu patrón [with] y luego invertir el resultado.

Es necesario que coincidan [, no seguida de ], seguido de with (y entonces el patrón correspondiente para corchete cerrado)

Coincidencia de la [ y la with son fáciles.

\[with 

añadir una búsqueda hacia delante para excluir ], y también permiten que cualquier número de otros caracteres (.*)

\[(?!]).*with 

entonces el corchete correspondiente cerrado, es decir, la inversa con una búsqueda hacia atrás.

\[(?!]).*with.*\](?<1[) 

ajustar un poco más

\[(?!(.*\].*with)).*with.*\](?<!(with.*\[.*)) 

y ahora si inverso Ésta, usted debe tener el resultado deseado. (es decir, cuando esto devuelve 'verdadero', su patrón coincide y desea excluir esos resultados).

1

Creo que la solución más simple es emparejar de forma preventiva los pares equilibrados de corchetes y sus contenidos para que no interfieran mientras busca la palabra clave. Aquí hay un ejemplo:

string s = 
    @"[with0] 
    [ with0 ] 
    [sometext with0 sometext] 
    [sometext with0] 
    [with0 sometext] 


    with1 
    ] with1 
    hello with1 
    hello with1 world 
    hello [ world] with1 hello 
    hello [ world] with1 hello [world]"; 

Regex r = new Regex(@"\[[^][]*\]|(?<KEYWORD>\bwith\d\b)"); 
foreach (Match m in r.Matches(s)) 
{ 
    if (m.Groups["KEYWORD"].Success) 
    { 
    Console.WriteLine(m.Value); 
    } 
} 
+0

Subiendo votos esto, buen Alan. :) Créalo o no, solo he visto otras 3 preguntas sobre SO que usan esta técnica, a pesar de ver muchos problemas similares. – zx81

Cuestiones relacionadas