使用正则表达式保存子字符串

时间:2010-06-09 23:22:58

标签: java regex replace find capturing-group

我是Java(或任何语言)的正则表达式的新手,我想要使用它们进行查找。我不明白该怎么做的棘手部分是替换匹配的字符串中的内容。

例如,如果我正在寻找的行是

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

我能够编写一个找到该行的正则表达式,但找到“thing”这个词是什么(因为它可能在不同的行之间有所不同)是我的问题。我可能想要用其他东西替换该单词,或者将其保存在变量中以供日后使用。使用Java的正则表达式引擎有没有简单的方法呢?

2 个答案:

答案 0 :(得分:3)

是。你将它包装在“捕获组”中,这只是正则表达式中与有趣词匹配的部分的一些()。

以下是一个例子:

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.util.regex。 String类中有一些快捷方式,但这些是最灵活的

答案 1 :(得分:1)

问题规范不是很清楚,但这里有一些可行的想法:

使用外观和replaceAll/First

以下正则表达式匹配前面带有字符串\w+的{​​{1}},后跟字符串"{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")
);

参考


使用捕获组而不是外观

应该明智地使用外观。尤其是Java中的Lookbehinds非常有限。一种更常用的技术是使用捕获组来匹配 more 而不仅仅是有趣的部分。

以下正则表达式匹配之前的类似模式Person item6 [can {item STUFF [wrap]}] Cat item7 [meow meow {item STUFF [purr]}] Dog item8 [maybe perhaps {itemmmm thong [woof]}] ,但也包含\w+前缀和"{item "后缀。此外," ["中的m可以无限制地重复(在Java中的后视中无法匹配)。

item

打印:

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

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

我们的模式有3个捕获组:

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

请注意,我们无法简单地替换与(\{item+ )(\w+)( \[) \________/\___/\___/ group 1 2 3 匹配的内容,因为我们会匹配一些“无关”的部分。我们对替换它们并不感兴趣,因此我们捕获这些部分并将它们放回替换字符串中。我们引用Java中替换字符串中捕获的组的方式是使用"STUFF" sigil;因此,上例中的$$1

参考


使用$3以获得更大的灵活性

并非一切都可以用替换字符串完成。例如,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());

参考

  • java.util.regex.Pattern
  • java.util.regex.Matcher
    • group(int) - 访问单个捕获的字符串
    • appendReplacement - 不幸的是,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.Formatter - 在上面示例中的StringBufferprintf中使用

附件