В java pattern matcher (regex) как перебирать и заменять каждый текст другим текстом - PullRequest
0 голосов
/ 08 мая 2019

Я хочу проверить соответствие шаблона и, если шаблон соответствует, то я хотел заменить этот текст индексом тестового массива.

public class test {
    public static void main(String[] args) {
        String[] test={"one","two","three","four"}
        Pattern pattern = Pattern.compile("\\$(\\d)+");
        String text="{\"test1\":\"$1\",\"test2\":\"$5\",\"test3\":\"$3\",\"test4\":\"$4\"}";
        Matcher matcher = pattern.matcher(text);



while(matcher.find()) {
       System.out.println(matcher.groupCount());
       System.out.println(matcher.replaceAll("test"));
    }
  System.out.println(text);
}

}

текстовая строка, которую я хотел в этом формате, конечный результат:

{\"test1\":\"one\",\"test2\":\"$two\",\"test3\":\"three\",\"test4\":\"four\"}

, но цикл while завершается после одного совпадения, и "test" заменяется везде так:

{"test1":"test","test2":"test","test3":"test","test4":"test"}

Использование приведенного ниже кода II дает результат: public class test {

    public static void main(String[] args) {
        String[] test={"one","two","three","four"};
        Pattern pattern = Pattern.compile("\\$(\\d)+");
        String text="{\"test1\":\"$1\",\"test2\":\"$2\",\"test3\":\"$3\",\"test4\":\"$4\"}";
        Matcher m = pattern.matcher(text);
    StringBuffer sb = new StringBuffer();
    while (m.find()) {
        m.appendReplacement(sb, test[Integer.parseInt(m.group(1)) - 1]);
    }
    m.appendTail(sb);
    System.out.println(sb.toString());

}
}

Но если у меня есть массив замещающего текста, подобный этому

String[] test={"$$one","two","three","four"};

, то из-за $$ я получаю исключение в потоке "main" java.lang.IllegalArgumentException: Illegalгрупповая ссылка на java.util.regex.Matcher.appendReplacement (Matcher.java:857)

Ответы [ 2 ]

2 голосов
/ 08 мая 2019

Ваша проблема в следующей строке:

System.out.println(matcher.replaceAll("test"));

Если вы удалите его, цикл будет проходить через все совпадения.

В качестве решения вашей проблемы вы можете заменить цикл на что-то вроде этого:

Для Java 8:

StringBuffer out = new StringBuffer();
while (matcher.find()) {
    String r = test[Integer.parseInt(matcher.group(1)) - 1];
    matcher.appendReplacement(out, r);
}
matcher.appendTail(out);
System.out.println(out.toString());

Для Java 9 и выше:

String x = matcher.replaceAll(match -> test[Integer.parseInt(match.group(1)) - 1]);
System.out.println(x);

Это работает, только если вы замените $5 на $2, что, как я полагаю, является вашей целью.

Что касается знаков $ в строке замены, документация гласит:

Знак доллара ($) может быть включен в качестве литерала в строку замены, если ему предшествует обратная косая черта (\ $).

Другими словами, вы должны записать свой заменяющий массив как String[] test = { "\\$\\$one", "two", "three", "four" };

0 голосов
/ 08 мая 2019

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

      int count = 1;
      for (String s : test) {
         text = text.replace("$" + count++, s);
      }
      System.out.println(text);

Он печатает.

{"test1":"one","test2":"two","test3":"three","test4":"four"}

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