2012-03-21 12 views
7

sé que hay varias preguntas sobre la recursión de expresiones regulares en .net. Puedo escribir expresiones regex algo complejas pero esta recursión está más allá de mí, simplemente no puedo escribirla.obtener patrones internos recursivamente usando regex C#

Estas son las preguntas más cercanas a lo que quiero.

first question,second question.

pero coincide con toda la cadena, quiero que las coincidencias en una colección preferiblemente la más interna coincidan primero o en algún orden. También coincide en un personaje de apertura y un personaje de cierre. El mío es 2 caracteres para abrir y cerrar, [! y!]

mi cadena de entrada será algo como esto.

[!a='test' b='[!a='innertest' b='innervalue'!]'!] 

Tengo que encontrar la sección innertest, [!a='innertest' b='innervalue'!], primero y luego evaluarla a través de uno de mis árboles de expresión. luego evalúa el padre que lo contiene.

¿Alguien puede ayudar con esto?

Respuesta

11

Aquí hay un patrón que podría satisfacer sus necesidades:

^\[!((?<n>\w+='\[!)|(?<inner-n>!]')|\w+='(?!\[!)[^']*'|)*!](?!(n))$ 

Dará el elemento más interior de cada elemento en orden. Para explicar lo que quiero decir, teniendo en cuenta el código:

[!a='test' c='[!x='blah'!]' b='[!a='[!y='innermost'!]' b='innervalue'!]' !] 

Dará los siguientes resultados (de la colección de captura para el grupo "interior"):

x='blag' 
y='innermost' 
a='[!y='innermost'!]' b='innervalue' 

Así, para cada elemento x=y en el [! .. !], dará los partidos en orden desde lo más interno hacia afuera.

Si también desea que la expresión general para ser capturado se puede modificar de esta manera:

^(?<n>\[!)((?<n>\w+='\[!)|(?<inner-n>!]')|\w+='(?!\[!)[^']*'|)*(?<inner-n>!])(?!(n))$ 

El dar:

x='blag' 
y='innermost' 
a='[!y='innermost'!]' b='innervalue' 
a='test' c='[!x='blag'!]' b='[!a='[!y='innermost'!]' b='innervalue'!]' 

Y para explicar la expresión regular:

^  # start of string 
\[!  # start of overall [! .. !] 
(  # either ... 
    (?<n>\w+='\[!)|  # a complex x='[! .. !]' containing a nested [! .. !] - push this onto the stack 'n' 
    (?<inner-n>!]')| # end of a nested [! .. !] - pop stack 'n', and capture the contents into 'inner' 
    \w+='(?!\[!)[^']*'| # a simple x='asdf' with no nested [! .. !] 
    )     # or a space 
*  # as many times as you want 
!]  # the end of the overall [! .. !] 
(?!(n)) # assert that the 'n' stack is empty, no mismatched [! .. !] 
$  # end of string 
+0

esto se ve bien .. Gracias por su ayuda. Voy a probarlo. ¿Hay alguna manera de decir el orden, como más interna primero, ya que primero debo evaluarlo? –

+0

No directamente. Podría resolverlo utilizando las propiedades 'Capture.Start' y' Capture.Length' para cada captura, ya que eso le permitirá saber qué capturas contienen qué otras capturas. Sin embargo, si cada 'x = '...'' solo puede depender de lo que contenga, entonces esta orden debería funcionar bien. – porges

+0

está muy cerca de lo que quiero. gracias por su esfuerzo. ¡Debes ser un genio! Una última pregunta sobre esto. Si quisiera cambiar las etiquetas de apertura y cierre a [} y {], en lugar de [!,!], ¿Cómo va a | \ w + = '(?! \ [!) [^'] * '| cambio de sección Intenté algunas cosas pero no las capturé. –

Cuestiones relacionadas