![](/img/trans.png)
[英]Java Regex - Using String's replaceAll method to replace newlines
[英]Using Java's replaceAll to replace the whole string
我正在尝试使用以下代码替换整个字符串:
代码: String a = "Hello"; String b = a.replaceAll("(?s).*", "US");
String a = "Hello"; String b = a.replaceAll("(?s).*", "US");
输出:
USUS
问题:为什么字符串“ US”重复两次? 如何使用正则表达式使用replaceAll函数替换整个字符串?
为什么需要这样做:我需要使用在其中提供的值来选择json文件中指定的替换模式。 在此模型中,我想赋予用户(json configurer)独立性以定义一种模式,以便可以替换整个字符串,而无需编写特殊的字符串替换处理代码。
这是因为Matcher
类如何处理可能与空字符串匹配的模式。 String
的replaceAll
方法被定义为与Matcher
的replaceAll
方法以相同的方式工作,如下所示:
此方法首先重置此匹配器。 然后,它扫描输入序列以查找模式匹配。 不属于匹配项的字符将直接附加到结果字符串中; 匹配项将在结果中替换为替换字符串。 替换字符串可能包含对捕获的子序列的引用,如appendReplacement方法中那样。
当匹配器尝试查找模式时,如果源中的子序列为空字符串,则匹配器将返回空字符串,但随后将当前索引增加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中看到它。 我想这意味着将来的JRE版本可能会表现不同,尽管这似乎不太可能。
这是因为.*
可以匹配一个空字符串。 因此第一个匹配项是所有字符串(从头开始),第二个匹配项是空字符串(从字符串中最后一个字符之后的最后位置开始)
您可以使用+
量词代替*
来避免这种现象。 但是它不会替换空字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.