使用Java的replaceAll替换整个字符串

Sno*_*yMe 4 java regex replaceall

我正在尝试使用以下代码来替换整个字符串:

代码: String a = "Hello"; String b = a.replaceAll("(?s).*", "US"); 输出:

USUS
Run Code Online (Sandbox Code Playgroud)

问题:为什么字符串“US”重复两次?如何使用正则表达式使用replaceAll函数替换整个字符串?

为什么我需要这样做:我需要使用其中给出的值来选择 json 文件中指定的替换模式。在此模型中,我想赋予用户(json 配置程序)独立性来定义一个模式,以便可以替换整个字符串,而无需编写字符串替换的特殊处理代码。

ajb*_*ajb 5

这是因为该类如何Matcher处理可能与空字符串匹配的模式。方法replaceAll的定义与方法的String工作方式相同,其工作方式如下:replaceAllMatcher

该方法首先重置该匹配器。然后它扫描输入序列以查找模式的匹配项。不属于匹配部分的字符将直接附加到结果字符串中;结果中的匹配项将被替换字符串替换。替换字符串可能包含对捕获的子序列的引用,如在appendReplacement 方法中一样。

当匹配器尝试查找模式时,如果源中的子序列是空字符串,则匹配器返回空字符串,但随后将当前索引增加 1,这样就不会返回空字符串的无限循环。那么它的运作方式如下"Hello"

1) 匹配器寻找.*. 由于这是一个贪婪匹配,匹配尽可能多的字符,因此它将找到子字符串"Hello",并使用它,将其替换为"US"。当前索引随后位于'o'.

2)匹配器再次寻找.*。由于它位于输入的末尾,但该模式允许匹配空字符串,因此它会匹配空字符串并将其替换为另一个"US". 但随后它会提高当前索引,该索引现在位于源末尾之后的位置。

3) 匹配器再次查找.*,但由于当前索引超出了源的末尾,因此它不会找到任何内容。

要了解它的运作方式,请尝试使用".*?"as 模式。现在,匹配器将始终使用空字符串,因为?告诉它使用尽可能短的字符串。每次找到空字符串时,它还会将当前索引加 1。结果:

a.replaceAll("(?s).*?", ".-")  //returns
".-H.-e.-l.-l.-o.-"
Run Code Online (Sandbox Code Playgroud)

也就是说,它将每对字符之间的所有空字符串替换为".-", 并保留实际字符。

寓意:要非常小心可能匹配空字符串的模式。

更多:在阅读您的评论后,您指出该模式可以由用户输入,我认为您可以使用它作为测试,看看该模式是否可以匹配空字符串:

if ("".matches(inputPattern)) {
    // ???
}
Run Code Online (Sandbox Code Playgroud)

我不确定你会用它做什么。也许情况总是如此,如果这是真的,您将在末尾replaceAll添加一个额外的内容,并且您可以安全地删除它。US或者你可以告诉他们尝试不同的模式。

聚苯硫醚。我不确定匹配器的这种行为(即当匹配为空字符串时将当前索引增加 1)记录在哪里。我在javadoc中没有看到它Matcher。我认为这意味着 JRE 的未来版本可能会有不同的行为,尽管这似乎不太可能。