получить внутренние шаблоны рекурсивно, используя регулярное выражение c # - PullRequest
7 голосов
/ 22 марта 2012

я знаю, что есть несколько вопросов о рекурсии в .net. Я могу написать несколько сложных выражений регулярных выражений, но эта рекурсия мне не подходит, я просто не могу ее написать.

Это вопросы, наиболее близкие к тому, что я хочу.

первый вопрос, второй вопрос .

но это соответствует всей строке, я хочу, чтобы совпадения в коллекции были предпочтительнее самого внутреннего совпадения или в каком-то порядке. Также это соответствует одному открывающему символу и одному закрывающему символу. Мой 2 символа для открытия и закрытия, [! и!]

моя строка ввода будет выглядеть примерно так.

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

Мне нужно сначала найти самый внутренний раздел, [!a='innertest' b='innervalue'!],, а затем оценить его через одно из моих деревьев выражений. затем оцените родительский, содержащий его.

Может кто-нибудь помочь с этим?

1 Ответ

12 голосов
/ 22 марта 2012

Вот шаблон, который может удовлетворить ваши потребности:

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

Это даст самый внутренний элемент для каждого элемента в порядке. Чтобы объяснить, что я имею в виду, приведем код:

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

Это даст следующие совпадения (в коллекции перехвата для группы «внутренний»):

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

Таким образом, для каждого элемента x=y в [! .. !] он будет давать совпадения в порядке от самого внутреннего к внешнему виду.

Если вы также хотите, чтобы общее выражение было захвачено, вы можете изменить его следующим образом:

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

Предоставление:

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

И чтобы объяснить регулярное выражение:

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