Java 正则表达式和替换

3

你好,我正在尝试理解Java正则表达式替换。我有很多正则表达式和替换要应用于文件中的文本。我想读取正则表达式并在文本上应用替换。 例如,我想在以下示例中将text替换为variable

import java.util.regex.*;
public class regex1{
public static void main(String args[]){
    String s1 = "cat catches dog text";
    Pattern p1 = Pattern.compile("\\s*cat\\s+catches\\s*dog\\s+(\\S+)");
    Matcher m1 = p1.matcher(s1);
    if (m1.find()){
        System.out.println(m1.group(1));
        s1 = m1.replaceFirst("variable $1");
        System.out.println(s1);
    }
    else{
        System.out.println("Else");
    }
}    
}

但我得到的输出是

text
variable text

有人可以解释一下Java中的group和replacement是如何工作的吗?如何获得正确的输出?


如果你只是想在字符串中将“text”替换为“variable”,你不需要使用正则表达式。如果你想做更多的事情,那么就展示真实的代码吧。 - Rohit Jain
你在表达式末尾只有一个与“text”匹配的组。因此只有一个组 :-)(或整个匹配(0))。 - Bart
@Bart 是的,我明白了,我的理解是它将把第一组“text”替换为“variable”。但实际上并没有这样。正确的正则表达式是什么? - Netro
Netro,你想要在句子“猫抓住了狗的文本”中将文本替换为变量吗? - SSaikia_JtheRocker
5个回答

2
请使用以下代码:
String s1 = "cat catches dog text";
Pattern p1 = Pattern.compile("\\s*cat\\s+catches\\s*dog\\s+(\\S+)");
Matcher m1 = p1.matcher(s1);
if (m1.find()){
    s1 = m1.replaceFirst(s1.substring(0, m1.start(1)) + "variable");
}
else{
    System.out.println("Else");
}
System.out.println(s1);
// cat catches dog variable

1

试试这个

import java.util.regex.*;
public class regex1{
public static void main(String args[]){
    String s1 = "cat catches dog text";
    Pattern p1 = Pattern.compile("\\s*cat\\s+catches\\s*dog\\s+(\\S+)");
    Matcher m1 = p1.matcher(s1);
    if (m1.find()){
        System.out.println(m1.group(1));
        s1 = s1.replaceFirst(m1.group(1),"variable");
        System.out.println(s1);
    }
    else{
        System.out.println("Else");
    }
}
}

myMatcher.replaceAll("replacement")myString.replaceAll("regex", "replacement") 的结果完全相同,区别只在于速度。摘自 http://www.regular-expressions.info/java.html - Enigmadan
使用s1.replaceFirst(m1.group(1),"variable");m1.replaceFirst(m1.group(1),"variable");有微妙的区别。后者更容易解决这个问题。 - Netro

1

我不完全确定你想要做什么。如果你想用 variable 替换 \\s*cat\\s+catches\\s*dog\\s+ 后面的单词,也许可以尝试这种方法。

String s1 = "cat catches dog text";
Pattern p1 = Pattern.compile("(\\s*cat\\s+catches\\s*dog\\s+)(\\S+)");
Matcher m1 = p1.matcher(s1);
if (m1.find()) {
    System.out.println(m1.group(2));
    s1 = m1.replaceFirst("$1variable");
    System.out.println(s1);
} else {
    System.out.println("Else");
}

现在group 1是(\\s*猫\\s+捕捉\\s*狗\\s+),您将其放回替换为$1并在末尾添加变量

输出:

text
cat catches dog variable

顺便说一下,如果你想使用replaceFirstreplaceAll,就不需要调用if(m1.find())。只需像这样使用:

String s1 = "cat catches dog text";
Pattern p1 = Pattern.compile("(\\s*cat\\s+catches\\s*dog\\s+)(\\S+)");
Matcher m1 = p1.matcher(s1);
s1 = m1.replaceFirst("$1variable");
System.out.println(s1);

如果您不再需要Pattern和Matcher,只需

String s1 = "cat catches dog text";
s1.replaceFirst("(\\s*cat\\s+catches\\s*dog\\s+)(\\S+)","$1variable");

0

String.replaceFirst接受两个参数:正则表达式和替换字符串。

因此,在您的示例中进行替换,

s1 = s1.replaceFirst("variable $1");

使用

s1 = s1.replaceFirst(m1.group(1), "variable");

2
myMatcher.replaceAll("replacement")myString.replaceAll("regex", "replacement") 的结果完全相同,区别只在于速度。摘自 http://www.regular-expressions.info/java.html - Enigmadan
根据Ruchira的建议,答案是s1 = s1.replaceFirst(m1.group(1), "variable"); - Netro

0

$1 是一种回溯引用的方法,它包括第一组括号($1)中的内容。

在您的情况下,$1 引用了匹配器 m1 中创建的第一个引用。对单词“text”的引用。

代码解释

                        referenced by $1
                             ↓↓↓↓
String s1 = "cat catches dog text";
                                                        reference $1
                                                           ↓    ↓
Pattern p1 = Pattern.compile("\\s*cat\\s+catches\\s*dog\\s+(\\S+)");

正则表达式这里的解释。将鼠标悬停在着色文本上以获取解释。

需要注意的是,\S(大写'S')匹配任何非空白字符,而+是贪婪的。这意味着我们获取的是“下一个空格之前的所有非空白字符”,或者简单地说,我们获取的是下一个单词。

在这种情况下,被匹配的单词恰好是“text”。

Matcher m1 = p1.matcher(s1);

m1现在将匹配"猫抓住狗的文本"

s1 = m1.replaceFirst("variable $1");

s1 被设置为 s1 ("cat catches dog text"),其中第一次出现的 m1 (第一次出现的 '"cat catches dog" 后跟任何单词') 被替换为 '"variable" 后跟同样的单词'

如果你真的想要用变量替换单词 "text",那么你需要删除 $1

s1 = m1.replaceFirst("variable");

s1 被设置为 s1 ("cat catches dog text"),其中第一次出现的 m1 (即 '"cat catches dog" 后跟任何单词' 的第一次出现) 被替换为 '"variable"'

如果是这种情况,实际上您不需要在 RegEx 模式中包含括号。如果您不打算进行回溯,则它们没有用处(在此情况下)。


感谢您花费这么长时间来解决问题。这也是我的想法,但它没有起作用。它给出了“变量”的答案。Ruchira提供的解决方案很好。 - Netro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接