2012-03-21 22 views
7

Wiem, że jest kilka pytań na temat rekursji regex w .net. Mogę napisać nieco skomplikowane wyrażenia regularne, ale ta rekursja jest poza mną, po prostu nie jestem w stanie jej napisać.Uzyskiwanie wewnętrznych wzorców rekursywnie za pomocą regex C#

To są pytania najbliżej tego, co chcę.

first question,second question.

ale pasuje do całego ciągu, chcę, aby mecze w kolekcji najlepiej najpierw były najgłębsze lub w jakiejś kolejności. Pasuje również do jednej postaci otwierającej i jednej postaci zamykającej. Mój jest 2 znaki do otwierania i zamykania, [! i!]

Mój łańcuch wejściowy będzie podobny do tego.

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

Muszę znaleźć sekcję innertest, [!a='innertest' b='innervalue'!], a potem oceniać go przez jeden z moich drzew ekspresyjnych. następnie oceń element macierzysty, który go zawiera.

Czy ktoś może w tym pomóc?

Odpowiedz

11

Oto wzór, który może zaspokoić swoje potrzeby:

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

To daje najgłębsze element dla każdego elementu w kolejności. Aby wyjaśnić, co mam na myśli, biorąc pod uwagę kod:

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

To daje następujące wyniki (w kolekcji przechwytywania dla grupy „wewnętrznej”):

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

Tak więc, dla każdego x=y elementu [! .. !], da to mecze w kolejności od najbardziej wewnętrznej na zewnątrz.

Jeśli chcesz także ogólny wyraz do niewoli można go zmodyfikować tak:

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

Dawanie:

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

I wyjaśnić regex:

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

to wygląda dobrze. Dziękuję za pomoc. zamierzam to wypróbować. czy istnieje sposób, aby powiedzieć porządek, jak najdalej, ponieważ najpierw muszę to ocenić. –

+0

Nie bezpośrednio. Można to sprawdzić za pomocą właściwości 'Capture.Start' i' Capture.Length' dla każdego przechwytywania, ponieważ pozwoli to stwierdzić, które przechwytywania zawierają inne przechwytywania. Jednakże jeśli każde 'x = '...'' może zależeć tylko od tego, co zawiera, to ta kolejność powinna działać poprawnie. – porges

+0

jest bardzo blisko tego, co chcę. dziękuję za Twój wysiłek. Musisz być geniuszem !!! Jedno ostatnie pytanie na ten temat. Gdybym chciał zmienić znaczniki otwierające i zamykające na [} i {], zamiast [!,!], Jak będzie | \ w + = '(?! \ [!) [^'] * '| zmiana sekcji. Próbowałem kilku rzeczy, ale go nie uchwyciłem. –

Powiązane problemy