Сохранение подстрок с помощью регулярных выражений


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

Например, если строка, которую я ищу, является

Person item6 [can {item thing [wrap]}]
Я могу написать регулярное выражение, которое находит эту строку, но найти, что такое слово "вещь" (поскольку оно может отличаться среди разных строк), - это моя проблема. Возможно, я захочу либо заменить это слово чем-то другим. иначе или сохраните его в переменной на потом. Есть ли простой способ сделать это с помощью движка регулярных выражений Java?
2 2

2 ответа:

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

Вот пример:

public static void main(String[] args) {

    Pattern pat = Pattern.compile("testing (\\d+) widgets");

    String text = "testing 5 widgets";

    Matcher matcher = pat.matcher(text);

    if (matcher.matches()) {
        System.out.println("Widgets tested : " + matcher.group(1));
    } else {
        System.out.println("No match");
    }

}

Pattern и Matcher происходят из java.утиль.регулярное выражение. В классе String есть несколько ярлыков, но они являются наиболее гибкими

Спецификация задачи не очень ясна, но вот некоторые идеи, которые могут сработать:

Используйте lookarounds и replaceAll/First

Следующее регулярное выражение соответствует \w+, которому предшествует строка "{item " и за которой следует строка " [". Lookarounds используются только для точного соответствия \w+. Метасимволы { и [ экранируются по мере необходимости.

String text =
    "Person item6 [can {item thing [wrap]}]\n" +
    "Cat item7 [meow meow {item thang [purr]}]\n" +
    "Dog item8 [maybe perhaps {itemmmm thong [woof]}]" ;

String LOOKAROUND_REGEX = "(?<=\\{item )\\w+(?= \\[)";

System.out.println(
    text.replaceAll(LOOKAROUND_REGEX, "STUFF")
);

Это отпечатки пальцев:

Person item6 [can {item STUFF [wrap]}]
Cat item7 [meow meow {item STUFF [purr]}]
Dog item8 [maybe perhaps {itemmmm thong [woof]}]

Ссылки


Используйте группы захвата вместо lookarounds

Lookarounds следует использовать разумно. Lookbehinds в частности на Java очень ограничен. Более распространенный метод заключается в использовании групп захвата для сопоставления большего, чем просто интересные части.

Следующее регулярное выражение соответствует аналогичному шаблону из перед, \w+, но также включает префикс "{item " и суффикс " [". Кроме того, m в item может повторяться без ограничений (что-то, что не может быть сопоставлено в lookbehind в Java).

String CAPTURING_REGEX = "(\\{item+ )(\\w+)( \\[)";

System.out.println(
    text.replaceAll(CAPTURING_REGEX, "$1STUFF$3")
);

Это печатает:

Person item6 [can {item STUFF [wrap]}]
Cat item7 [meow meow {item STUFF [purr]}]
Dog item8 [maybe perhaps {itemmmm STUFF [woof]}]

Наш шаблон имеет 3 группы захвата:

(\{item+ )(\w+)( \[)
\________/\___/\___/
 group 1    2    3
Обратите внимание, что мы не можем просто заменить то, что мы сопоставили с "STUFF", потому что мы сопоставляем некоторые "посторонние" части. Мы не заинтересованы в их замене, поэтому мы захватываем эти части и просто помещаем их обратно замещающая строка. Способ, которым мы ссылаемся на то, что группа, захваченная в заменяющих строках в Java, использует сигил $; таким образом, $1 и $3 в приведенном выше примере.

Ссылки


Используйте a Matcher для большей гибкости

Не все можно сделать с помощью заменяющих строк. Например, в Java нет постпроцессинга для капитализации захваченной строки. В этих более общих чертах в сценариях замены можно использовать цикл Matcher, например:
Matcher m = Pattern.compile(CAPTURING_REGEX).matcher(text);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    System.out.println("Match found");
    for (int i = 0; i <= m.groupCount(); i++) {
        System.out.printf("Group %d captured <%s>%n", i, m.group(i));
    }
    m.appendReplacement(sb,
        String.format("%s%s %<s and more %<SS%s",
            m.group(1), m.group(2), m.group(3)
        )
    );
}
m.appendTail(sb);

System.out.println(sb.toString());

Вышеупомянутые отпечатки:

Match found
Group 0 captured <{item thing [>
Group 1 captured <{item >
Group 2 captured <thing>
Group 3 captured < [>

Match found
Group 0 captured <{item thang [>
Group 1 captured <{item >
Group 2 captured <thang>
Group 3 captured < [>

Match found
Group 0 captured <{itemmmm thong [>
Group 1 captured <{itemmmm >
Group 2 captured <thong>
Group 3 captured < [>

Person item6 [can {item thing thing and more THINGS [wrap]}]
Cat item7 [meow meow {item thang thang and more THANGS [purr]}]
Dog item8 [maybe perhaps {itemmmm thong thong and more THONGS [woof]}]

Ссылки

Вложения