Как сопоставить строку в круглых скобках (вложенных) в Java?

Я хотел бы сопоставить строку в скобках, как:

(i, j, k(1))
^^^^^^^^^^^^

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

Редактировать:

Я хочу найти строковый блок и найти что-то вроде u(i, j, k), u(i, j, k(1)) или просто u(<anything within this paired parens>)и заменить их на __u%array(i, j, k) а также __u%array(i, j, k(1)) для моего приложения для перевода на Фортран.

3 ответа

Решение

Как я уже сказал, вопреки распространенному мнению (не верьте всему, что говорят люди), сопоставление вложенных скобок возможно с регулярным выражением.

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

Но не верьте мне на слово. Позволь мне показать тебе. Регулярное выражение:

\([^()]*\)

Соответствует одному уровню. Для двух уровней вам понадобится:

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

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

Твоя проблема:

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

String fortranCode = "code code u(i, j, k) code code code code u(i, j, k(1)) code code code u(i, j, k(m(2))) should match this last 'u', but it doesnt.";
String regex = "(\\w+)(\\(([^()]*|\\([^()]*\\))*\\))"; // (\w+)(\(([^()]*|\([^()]*\))*\))
System.out.println(fortranCode.replaceAll(regex, "__$1%array$2"));

Входные данные:

code code u(i, j, k) code code code code u(i, j, k(1)) code code code u(i, j, k(m(2))) should match this last 'u', but it doesnt.

Выход:

code code __u%array(i, j, k) code code code code __u%array(i, j, k(1)) code code code u(i, j, __k%array(m(2))) should match this last 'u', but it doesnt.

Нижняя линия:

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

Примечание: некоторые разновидности регулярных выражений поддерживают оператор вложенности R (Java не делает, PCRE движки, как PHP и Perl делают), что позволяет вам вкладывать произвольное количество уровней. С ними вы можете сделать: \(([^()]|(?R))*\) ,

Раздели свою работу. Пусть регулярное выражение будет:

([a-z]+)\((.*)\)

Первая группа будет содержать идентификатор, вторая - параметры. Затем действуйте так:

private static final Pattern PATTERN = Pattern.compile("([a-z]+)\\((.*)\\)");

// ...

final Matcher m = Pattern.matcher(input);

if (!m.matches())
    // No match! Deal with it.

// If match, then:

final String identifier = m.group(1);
final String params = m.group(2);

// Test if there is a paren
params.indexOf('(') != -1;

замещать [a-z]+ с любым идентификатором может быть в Fortran.

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

Регулярное выражение для соответствия внешним скобкам

Другие вопросы по тегам