2

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

例如,如果我要查找的行是

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

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

4

2 回答 2

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

于 2010-06-09T23:49:17.230 回答
1

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

使用环视和replaceAll/First

以下正则表达式匹配\w+前面为 string"{item "且后面为 string 的" ["。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]}]

参考


使用捕获组而不是环视

应明智地使用环视。特别是在 Java 中的 Lookbehinds 非常有限。一种更常用的技术是使用捕获组来匹配更多有趣的部分。

以下正则表达式与之前的类似模式匹配\w+,但也包括"{item "前缀和" ["后缀。此外,minitem可以无限制地重复(在 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在上面的例子中。

参考


使用 aMatcher以获得更大的灵活性

并非所有事情都可以用替换字符串来完成。例如,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]}]

参考

附件

于 2010-06-10T08:26:36.390 回答