Как заменить содержимое регулярного выражения с именем Capture Group в Java

#java #regex

#java #регулярное выражение

Вопрос:

У меня есть проект Java и следующий шаблон регулярных выражений с именованными группами захвата:

 (?<department>w (-w)??)s{1,5}(?<number>w (-w )?)-(?<section>w )s(?<term>d )s(?<campus>w{2})
  

Я хотел заменить значение одной из именованных групп символом подстановки (*). Похоже, что все методы replace в классе Matcher привязаны к замене определенного значения регулярного выражения. Поскольку не гарантируется, что строка будет уникальной, я хочу заменить ее именем группы.

Есть ли способ использовать класс сопоставления для обеспечения этой возможности замены?

Ответ №1:

Я понял, что могу использовать методы start и end сопоставителя для определения диапазона символов, которые необходимо заменить. Затем я могу использовать StringBuilder для удаления диапазона и вставки указанного заменяющего значения. Я написал следующий метод для решения этой ситуации.

 public static String replaceNamedGroup(String source, Pattern pattern, String groupName, String replaceValue) {
  if (source == null || pattern == null) {
    return null;
  }

  Matcher m = pattern.matcher(source);
  if (m.find()) {
    int start = m.start(groupName);
    int end = m.end(groupName);
    StringBuilder sb = new StringBuilder(source);
    sb = sb.delete(start, end);
    if (replaceValue != null) {
      sb = sb.insert(start, replaceValue);
    }
    return sb.toString();
  } else {
    return source;
  }
}
  

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

 String str = "ABC 123-123 1234 AB";
Pattern pattern = Pattern.compile("(?<department>w (-w)??)s{1,5}(?<number>w (-w )?)-(?<section>w )s(?<term>d )s(?<campus>w{2})");
String output = replaceNamedGroup(str, pattern, "term", "*");
//outputs Output: ABC 123-123 * AB
System.out.println("Output: "   output);
  

Комментарии:

1. Вместо delete(start, end) insert(start, replaceValue) в коде следует использовать replace(start, end, replaceValue) , поэтому текст, следующий за замененным разделом, не нужно перемещать дважды. Используйте тернарный оператор для обработки null , если это необходимо: (replaceValue != null ? replaceValue : "")