Tengo un problema con el ajuste fino de regex
Pregunta
Tengo regex que estaba bien, pero como salió bien no funciona bien en algunas situaciones
Esté atento a la vista previa del mensaje porque el editor de mensajes hace algunas cosas difíciles con " \ "
[\ []? [\ ^% # \ $ \ * @ \ -;]. *? [\ ^% # \ $ \ * @ \ -;] [\]]
su tarea es encontrar un patrón que en general se vea así
[ABA]
- A - char del conjunto ^,%, #, $, *, @, - ,;
- B - algún texto
- [y] están incluidos en el patrón
encuentre todas las ocurrencias de este patrón en la cadena de prueba
Zorro negro [# sample1 #] [% sample2%] - [# sample3 #] come bloques.
pero en lugar de la lista esperada de coincidencias
- " [# muestra1 #] "
- " [% muestra2%] "
- " [# sample3 #] "
Me sale esto
- " [# muestra1 #] "
- " [% muestra2%] "
- " - [# muestra3 #] "
Y parece que este problema también ocurrirá con otros caracteres en el conjunto " A " ;. Entonces, ¿alguien podría sugerir cambios en mi expresión regular para que funcione como lo necesito?
y algo menos importante, cómo hacer que mi expresión regular excluya patrones que se vean así
[ABC]
- A - char del conjunto ^,%, #, $, *, @, - ,;
- B - algún texto
- C - char del conjunto ^,%, #, $, *, @, - ,; que no sea A
- [y] están incluidos en el patrón
por ejemplo
[$ muestra1 #] [% muestra2 @] [% muestra3;]
gracias de antemano
MTH
Solución
\[([%#$*@;^-]).+?\1\]
aplicado al texto:
Black fox [#sample1#] [%sample2%] - [#sample3#] [%sample4;] eats blocks.
coincide con
[#sample1#font>
[%sample2%font>
[#sample3##<
- pero no
[%sample4;font>
EDITAR
Esto funciona para mí (salida como se esperaba, regex aceptado por C # como se esperaba):
Regex re = new Regex(@"\[([%#$*@;^-]).+?\1\]");
string s = "Black fox [#sample1#] [%sample2%] - [#sample3#] [%sample4;] eats blocks.";
MatchCollection mc = re.Matches(s);
foreach (Match m in mc)
{
Console.WriteLine(m.Value);
}
Otros consejos
¿Por qué el primer "? " en " [[]? "
\[[\^%#\$\*@\-;].*?[\^%#\$\*@\-;]\]
detectaría sus diferentes cadenas muy bien
Para ser más precisos:
\[([\^%#\$\*@\-;])([^\]]*?)(?=\1)([\^%#\$\*@\-;])\]
detectaría [ABA]
\[([\^%#\$\*@\-;])([^\]]*?)(?!\1)([\^%#\$\*@\-;])\]
detectaría [ABC]
Tiene una correspondencia opcional del corchete de apertura:
[\]]?
Para la segunda parte de su pregunta (y quizás para simplificar) intente esto:
\ [\% [^ \%] + \% \] | \ [\ # [^ \ #] + \ # \] | \ [\ $ [^ \ $] + \ $ \]
En este caso hay un subpatrón para cada delimitador posible. El | el carácter es " OR " ;, por lo que coincidirá si alguna de las 3 subexpresiones coincide.
Cada subexpresión:
- Soporte de apertura
- Char Especial
- Todo lo que no es un char especial (1)
- Carácter especial
- Cierre de respaldo
(1) puede necesitar agregar exclusiones adicionales como ']' o '[' para que no coincida accidentalmente en un gran cuerpo de texto como:
[% MyVar #] bla, bla [$ OtherVar%]
Rob