Сохранение подстрок с помощью регулярных выражений
Я новичок в регулярных выражениях на Java (или любом другом языке, если на то пошло), и я хочу сделать находку, используя их. Самое сложное, что я не понимаю, как это сделать, - это заменить что-то внутри строки, которая соответствует.
Например, если строка, которую я ищу, является
Person item6 [can {item thing [wrap]}]
Я могу написать регулярное выражение, которое находит эту строку, но найти, что такое слово "вещь" (поскольку оно может отличаться среди разных строк), - это моя проблема. Возможно, я захочу либо заменить это слово чем-то другим. иначе или сохраните его в переменной на потом. Есть ли простой способ сделать это с помощью движка регулярных выражений Java?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
Не все можно сделать с помощью заменяющих строк. Например, в Java нет постпроцессинга для капитализации захваченной строки. В этих более общих чертах в сценариях замены можно использовать циклMatcher
для большей гибкости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]}]
Ссылки
java.util.regex.Pattern
java.util.regex.Matcher
group(int)
- доступ к отдельным захваченным строкамappendReplacement
-- к сожалению,StringBuffer
- толькоjava.util.Formatter
- используется вprintf
иString.format
выше примерВложения