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

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

Например, если искомая строка -

Person item6 [can {item thing [wrap]}]

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

Ответы [ 2 ]

3 голосов
/ 10 июня 2010

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

Вот пример:

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 and Matcherприходят из java.util.regex.В классе String есть несколько ярлыков, но они наиболее гибкие

1 голос
/ 10 июня 2010

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

Используйте 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 следует использовать разумно. В частности, взгляд на Java очень ограничен. Более распространенный метод - использовать группы захвата, чтобы сопоставить больше , чем просто интересные части.

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

Ссылки


Используйте 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]}]

Ссылки

Вложения

...