2012-04-23 1 views
0

Я хотел бы использовать regex, чтобы заглянуть внутрь строки для наименьшей последовательности, которая соответствует начальному и конечному разделителям (с учетом символа пробега). Например, если бы у меня была следующая строка, я бы хотел найти самые низкие совпадения [ two ] и [ four \[ five \] ], игнорируя совпадение, они содержатся в [ one ... three ... six].Разбор вложенных совпадений с использованием regex

zero [ one [ two ] three [ four \[ five \] ] six ] seven 

До сих пор у меня есть следующее регулярное выражение, которое использует отрицательные просмотровые задом, чтобы проверить и не совсем кэширование во втором матче последнего ].

(\[)(?:(?!(?:[^\\])\1|\]).)*] 

Моя цель состоит в том, чтобы иметь простой парсер, который я могу использовать для обработки простых вложенных командных блоков.

ответ

1

следующие работы:

\[(?:\\[\[\]]|[^\[\]])*] 

Смотреть это работает: http://www.rubular.com/r/cAajtm2wxw

Объяснение:

\[    # opening bracket 
(?:    # start of non-capturing group (repeat zero or more times) 
    \\[\[\]]   # backslash followed by [ or ] 
    |    # OR 
    [^\[\]]   # any character except [ or ] 
)*    # end of non-capturing group 
]     # closing bracket 

Обратите внимание, что это не совсем безопасно, потому что в строке, как [ one \\[ two ] three ] обратный слеш ускользнул, поэтому обратная косая черта перед [ не должна его избегать.

Чтобы исправить это, вы можете использовать следующее:

\[(?:(?<!\\)(?:\\\\)*\\[\[\]]|[^\[\]])*] 

Это меняет единственный спасся обратный слэш \\ в исходном регулярном выражении к следующему регулярному выражению, которое проверяет наличие нечетного числа обратной косой черты:

(?<!\\)   # fail if previous character is a backslash 
(?:\\\\)*   # some even number of backslashes 
\\    # one more backslash to make it odd 

http://www.rubular.com/r/BhQzLQpyB9

+0

Спасибо! Вы помогли мне предвидеть проблемы, о которых я даже не думал. Кроме того, добавление творческой логики (с использованием 2 даже + 1 нечетных до 1 нечетного) довольно аккуратно. – Xeoncross