Замените запятую в скобках, используя регулярное выражение в Java - PullRequest
8 голосов
/ 13 сентября 2010

Я хочу заменить запятую только в скобках.

Например

 Progamming languages (Java, C#, Perl)

TO

Progamming languages (Java or C# or Perl)

но она не должна повторять запятую в следующей строке

Progamming languages Java, C#, Perl

КОД

Он будет заменен правильно, но не соответствует.

 String test  = "Progamming languages (Java, C#, Perl)";
 String test1 = "Progamming languages Java, C#, Perl"


 String foo = replaceComma(test);
 String foo1 = replaceComma(test1);


 private static String replaceComma(String test)
 {
    String patternStr= "\\((?:.*)(,)(?:.*)\\)";
    Pattern pattern = Pattern.compile(patternStr);
    Matcher matcher= pattern.matcher(test);

    if(matcher.matches())
    {
      return  test.replaceAll("(,)", " or ");
    }

    return  test;

 }

UPDATE

String.replaceAll("(,)", " or "); не будет работать, если у вас есть такая строка

String test = "Обучение, языки (Java, C #, Perl)";

, поэтому вы должны использовать код @polygenelubricants

Ответы [ 4 ]

7 голосов
/ 13 сентября 2010

Вы можете использовать положительное значение lookahead (?=…) вот так:

    String COMMA_INSIDE = ",(?=[^()]*\\))";
    String text = "a, b, c, (d, e, f), g, h, (i, j, k)";
    System.out.println(
        text.replaceAll(COMMA_INSIDE, " OR")
    );
    // a, b, c, (d OR e OR f), g, h, (i OR j OR k)

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

[^…] - это отрицательный класс символов . [^()] соответствует всему, кроме скобок. * - ноль или более повтор . \) (записанный как "\\)" как строковый литерал Java) соответствует буквально закрывающей скобке. Обратная косая черта экранирует то, что в противном случае является специальным метасимволом для группировки .

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

1 голос
/ 13 сентября 2010

Ваша ошибка использует matches вместо find здесь:

if (matcher.find())

Из документации :

  • Совпаденияметод пытается сопоставить всю входную последовательность с шаблоном.
  • Метод find сканирует входную последовательность в поисках следующей подпоследовательности, которая соответствует шаблону.также несколько упрощает проблему - он заменяет все запятыми, даже если в скобках есть только одна из них.Вероятно, не очень хорошая идея использовать регулярные выражения для такого рода задач.

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

0 голосов
/ 13 сентября 2010
String  replaceComma(String input)
{
 String[] strSplit=input.split("[\\(\\)]");
  if(strSplit.length==2)
   input=input.replaceAll(", "," or ");
 return input;
}

ОБНОВЛЕНИЕ : Для String, например "Изучение языков (Java, C #, Perl)"

String  replaceComma(String input)
{
String[] splitStr=input.split("[\\(\\)]");
 if(splitStr.length==2)
   input=input.replace(splitStr[1],splitStr[1].replaceAll(", ", " or "));
return input;
}
0 голосов
/ 13 сентября 2010

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

(?=X) позитивный взгляд

(?<=X) положительный взгляд за спиной

Отметьте правильно, вам нужен цикл вместо replaceAll. Но вы все равно можете использовать регулярное выражение, используя технику, которую я описал.

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