2012-03-21 8 views
7

so che ci sono diverse domande sulla ricorsione regex in .net. Riesco a scrivere espressioni regex piuttosto complesse, ma questa ricorsione è oltre me, non sono in grado di scriverlo.recupera ricorsivamente i modelli interni utilizzando regex C#

Queste sono le domande più vicine a quello che voglio.

first question,second question.

ma corrisponde all'intera stringa, voglio le corrispondenze in una raccolta preferibilmente la partita più interna prima o in un certo ordine. Inoltre corrisponde a un personaggio di apertura e un carattere di chiusura. Il mio è di 2 caratteri per l'apertura e la chiusura, [! e!]

la mia stringa di input sarà qualcosa del genere.

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

ho bisogno di trovare la sezione innertest, [!a='innertest' b='innervalue'!], prima e poi valutare attraverso uno dei miei alberi di espressione. quindi valutare quello principale che lo contiene.

Qualcuno può aiutare con questo?

risposta

11

Ecco uno schema che possa soddisfare le vostre esigenze:

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

che darà la voce più interno per ogni elemento in ordine. Per spiegare cosa intendo, dato il codice:

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

Vi darà le seguenti partite (della collezione di acquisizione per il gruppo "interno"):

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

Quindi, per ogni x=y elemento in il [! .. !], darà le partite in ordine dall'esterno verso l'esterno.

Se si desidera anche l'espressione complessiva da catturare è possibile modificare in questo modo:

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

Dare:

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

E per spiegare l'espressione regolare:

^  # 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

questo sembra buono .. grazie per il vostro aiuto. ho intenzione di provarlo. c'è un modo per dire l'ordine, come prima di tutto, poiché ho bisogno di valutarlo prima. –

+0

Non direttamente. Potresti elaborarlo usando le proprietà 'Capture.Start' e' Capture.Length' per ogni acquisizione, dal momento che ti consente di sapere quali acquisizioni contengono quali altre acquisizioni. Tuttavia, se ogni 'x = '...'' può solo dipendere da ciò che contiene, allora questo ordine dovrebbe funzionare correttamente. – porges

+0

è molto vicino a quello che voglio. grazie per l'impegno. Devi essere un genio !!! Un'ultima domanda su questo. Se volessi cambiare i tag di apertura e chiusura su [} e {], invece di [!,!], Come sarà il | \ w + = '(?! \ [!) [^'] * '| cambio di sezione. Ho provato alcune cose ma non l'ho catturato. –

Problemi correlati