Как я могу обработать несколько круглых скобок в регулярном выражении? - PullRequest
1 голос
/ 03 мая 2010

У меня есть строки этого типа:

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

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

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

Что, хотя это работает во многих случаях, похоже, не получится, если у меня что-то подобное:

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

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

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

Ответы [ 7 ]

4 голосов
/ 03 мая 2010

Помимо ленивого количественного определения, есть еще один способ:

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

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

3 голосов
/ 03 мая 2010

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

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

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

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

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

3 голосов
/ 03 мая 2010

Попробуйте:

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

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

Другое предложение:

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

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

1 голос
/ 03 мая 2010

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

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

1 голос
/ 03 мая 2010

Попробуйте это:

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

0 голосов
/ 03 мая 2010
$str =~ /^.*?\((.*)\)/
0 голосов
/ 03 мая 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...