Как обрабатывать вложенные скобки с помощью регулярных выражений?



Я придумал строку регулярного выражения, которая разбивает данный текст на 3 категории:




  • в скобках

  • в скобках

  • ни.


Вот так:



[.+?]|(.+?)|[w+ ?]+


Мое намерение состоит в том, чтобы использовать только внешний оператор. Итак, учитывая a(b[c]d)e, раскол будет следующим:

a || (b[c]d) || e


Он прекрасно работает с заданными скобками внутри скобок или скобками внутри скобок, но ломается, когда есть скобки внутри скобок и скобки внутри скобок. Для пример, a[b[c]d]e разбивается на



a || [b[c] || d || ] || e.


Есть ли способ справиться с этим, используя только регулярное выражение, не прибегая к использованию кода для подсчета количества открытых / закрытых скобок? Спасибо!
773   2  

2 ответов:

Стандарт1 регулярные выражения недостаточно сложны, чтобы соответствовать вложенным структурам. Лучший способ приблизиться к этому, вероятно, чтобы пересечь строку и отслеживать открытие / закрытие пар скобок.


1 я сказал стандартный , но не все механизмы регулярных выражений действительно стандартны. Вы можете сделать это с помощью Perl, например, используя рекурсивные регулярные выражения. Для пример:

$str = "[hello [world]] abc [123] [xyz jkl]";

my @matches = $str =~ /[^\[\]\s]+ | \[ (?: (?R) | [^\[\]]+ )+ \] /gx;

foreach (@matches) {
    print "$_\n";
}
[hello [world]]
abc
[123]
[xyz jkl]

EDIT: я вижу, вы используете Python; проверьте pyparsing.

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

def nested_matcher (n):
    # poor man's matched paren scanning, gives up after n+1 levels.
    # Matches any string with balanced parens or brackets inside; add
    # the outer parens yourself if needed.  Nongreedy.  Does not
    # distinguish parens and brackets as that would cause the
    # expression to grow exponentially rather than linearly in size.
    return "[^][()]*?(?:[([]"*n+"[^][()]*?"+"[])][^][()]*?)*?"*n

import re

p = re.compile('[^][()]+|[([]' + nested_matcher(10) + '[])]')
print p.findall('a(b[c]d)e')
print p.findall('a[b[c]d]e')
print p.findall('[hello [world]] abc [123] [xyz jkl]')

Это выведет

['a', '(b[c]d)', 'e']
['a', '[b[c]d]', 'e']
['[hello [world]]', ' abc ', '[123]', ' ', '[xyz jkl]']

Comments

    Ничего не найдено.