2011-05-14 49 views
7

necesito asociar toda la declaración siguiente:expresiones regulares incrustada {{juego

{{CalendarCustom|year={{{year|{{#time:Y}}}}}|month=08|float=right}} 

Básicamente siempre que haya un { es necesario que haya un correspondiente } con sin embargo muchos incrustado { } están dentro de la etiqueta original. Por ejemplo, {{match}} o {{ma{{tch}}}} o {{m{{a{{t}}c}}h}}.

tengo unas pocas cosas en este momento:

(\{\{.+?(:?\}\}[^\{]+?\}\})) 

Esto no acaba de funcionar.

+0

¿Qué es exactamente estás tratando de salir de la cadena? – Oded

+0

Solo quiero hacer coincidir todo el enunciado para poder eliminarlo. Al igual que hay otro texto que lo rodea y quiero hacer coincidir cualquier cosa dentro de {} paréntesis y eliminarlo. – thirsty93

+2

En general, las expresiones regulares no son la herramienta adecuada para hacer coincidir los paréntesis, ver. p.ej. [aquí] (http://stackoverflow.com/q/546433/577423). – Howard

Respuesta

15

El motor de expresiones regulares de .NET permite a juego recursiva:

result = Regex.Match(subject, 
    @"\{     # opening { 
     (?>    # now match... 
      [^{}]+   # any characters except braces 
     |     # or 
      \{ (?<DEPTH>) # a {, increasing the depth counter 
     |     # or 
      \} (?<-DEPTH>) # a }, decreasing the depth counter 
     )*     # any number of times 
     (?(DEPTH)(?!))  # until the depth counter is zero again 
     \}     # then match the closing }", 
    RegexOptions.IgnorePatternWhitespace).Value; 
+0

gracias por señalar esto. Aprendí algo hoy ... ¿Tiene un enlace que documenta ''? – Oded

+0

@Oded: 'DEPTH' es un nombre arbitrario; es simplemente un grupo de captura con nombre vacío' (? ) 'que en .NET cuenta el número de coincidencias; '(?<-id>) 'es lo mismo, simplemente disminuyendo el contador. Y '(? (ID) (?!))' solo coincide si el contador 'id' es cero. Esto está documentado en la página 436 de "Mastering Regular Expressions" de Friedl. –

+0

ese libro está en mi biblioteca, esperando a ser leído ... – Oded

4

Sugiero escribir un analizador/tokenizador simple para esto.

Básicamente, se recorre todos los personajes y empezar a contar los casos de { y } - incremento de { y decremento de }. Registre el índice de cada primer { y el índice de cada último } y tendrá los índices para sus expresiones incrustadas.

En este punto puede usar substring para obtener estos y quitarlos/reemplazarlos de la cadena original.

Consulte this pregunta y respuestas sobre por qué RegEx no es adecuado.

+0

Lo segundo. He visto a una empresa para la que solía trabajar, seguir el camino de analizar a través de expresiones regulares, y parece que va a ser más fácil. Es una gran curva de aprendizaje, pero valdrá la pena a largo plazo. Consulte ANTLR para obtener un punto de partida ... –

+0

Este es un ejemplo muy simple del uso de ANTLR para analizar y evaluar expresiones. Observe cuán simple es simplemente definir cuáles son los "tokens" válidos y luego espolvorear en el código fuente de Java en línea (también funciona con C#), y luego ANTLR hace el resto. http://www.antlr.org/wiki/display/ANTLR3/Expression+evaluator –

+0

Estoy creando algo que se ejecuta en xbox, por lo que no se permite ningún código no administrado. – thirsty93