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

标签 java regex replaceall

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

代码: 字符串 a = "你好"; String b = a.replaceAll("(?s).*", "US"); 输出:

USUS

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

为什么我需要这样做: 我需要使用那里给定的值来选择 json 文件中指定的替换模式。在这个模型中,我想给用户(json 配置器)独立性来定义一个模式,这样整个字符串都可以被替换,而我不必编写字符串替换的特殊处理代码。

最佳答案

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

This method first resets this matcher. It then scans the input sequence looking for a match of the pattern. Characters that are not part of the match are appended directly to the result string; the match is replaced in the result by the replacement string. The replacement string may contain references to captured subsequences as in the appendReplacement method.

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

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

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

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

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

a.replaceAll("(?s).*?", ".-")  //returns
".-H.-e.-l.-l.-o.-"

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

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

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

if ("".matches(inputPattern)) {
    // ???
}

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

PPS. 我不确定匹配器的这种行为(即当匹配为空字符串时将当前索引增加 1)记录在何处。我没有在 Matcher javadoc 中看到它。我想这意味着 future 版本的 JRE 可能会有所不同,尽管这似乎不太可能。

关于java - 使用 Java 的 replaceAll 替换整个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26240607/

相关文章:

Javascript 字符串替换 - 非字母数字字符的正则表达式,如反斜杠、大于等

java - ElasticSearch - 打开的文件太多

java - 并发任务执行

php - 使用 PHP+CSS 检测包含大写单词的行并使用粗体行设置样式

javascript - Javascript 正则表达式中的 g 和 m 修饰符有什么区别?

java - 正则表达式允许; JAVA 中至少 5 位数字并修剪前导/尾随分号

java - Java replaceAll 操作如何与反斜杠一起使用?

Java replaceAll ("\\s+") 与 replaceAll ("\\\\s+")

java - REST API 和多态性

java - 可编辑的 JComboBox 没有默认选择