2010-05-03 2 views
0

У меня есть строки этого типа:Как я могу обрабатывать несколько скобок в регулярном выражении?

текст (текст) более

То, что я хотел бы сделать, это иметь регулярное выражение, которое извлекает «больше текста» сегмент строки. До сих пор я использовал это регулярное выражение:

"^.*\\((.*)\\)$" 

который, хотя он работает на многих случаях, это, кажется, не в состоянии, если у меня есть что-то в этом роде:

текст (больше текста (даже больше текста))

что я получаю: даже больше текста)

что я хотел бы получить вместо этого:. более текст (даже больше текста) (в основном содержание внешней пары скобок)

ответ

4

Кроме ленивой квантификации, другой путь:

"^[^(]*\\((.*)\\)$" 

В обоих регулярных выражений, есть явно указано скобка ("\\(" с Java Строка побега) немедленно перед соответствующей группой. В оригинале до этого был .*, позволяющий что угодно (включая другие левые круглые скобки). В моих левых круглых скобках здесь не разрешено (есть negated character class), поэтому явно указанная левая скобка в самом внешнем.

+0

Спасибо, работал как шарм. Отметьте как ответ, когда 10 минут закончились. – npinti

+0

Это помогает объяснить ответ! – fastcodejava

3

Try:

"^.*?\\((.*)\\)$" 

Это должно сделать первое согласование менее жадным. Жадный означает, что он проглатывает все, что возможно, пока все еще получает общий шаблон.

Другой совет:

"^[^(]*\\((.*)\\)$" 

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

+0

+1, потому что вы написали тот же ответ, что и принятый. –

+0

@Martijn Courteaux: oO?! – Tomalak

+0

@ Томалак: Правильно! Также +1 для вас! –

-1

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

+1

Это неправильно. Он хочет включить закрывающие круглые скобки в соответствующей группе, чтобы соответствовать таким вещам, как «больше текста (даже больше текста)» –

3

Я рекомендую это (двойное экранирование от обратной косой черты удалены, так как это не является частью регулярных выражений):

^[^(]*\((.*)\) 

Matching с вашей версией (^.*\((.*)\)$) происходит следующим образом:

  1. Звезда соответствует жадности, поэтому ваш первый .* подходит к концу строки.
  2. Затем он обращается как можно больше, так что \( может совпадать - это будет последний вскрывающий палец в строке.
  3. Затем следующий .* снова направляется в конец строки.
  4. Затем он возвращается так же, как и \), например, к последнему заключительному парижу.

При использовании [^(]* вместо .*, он не может пройти мимо первого открытия Paren, поэтому первые открытия скобка (правильно один) в строке будет разграничить ваш суб-матч.

+1

+1 Мне нравится объяснение того, как это происходит, чтобы найти совпадение – Thorarin

1

Истинные регулярные выражения не могут считать круглые скобки; для этого требуется автомат выталкивания. В некоторых библиотеках регулярных выражений есть расширения для поддержки этого, но я не думаю, что Java делает (может быть неправильно, Java не является моим фортом).

BTW, другие ответы, которые я видел до сих пор, будут работать с приведенным примером, но будут разрываться, например, text (more text (even more text)) (another bit of text). Изменение жадности не компенсирует невозможность подсчета.

Смежные вопросы