Java 什么更有效:replaceFirst()或带有锚定正则表达式的replaceAll()?
我们有一个字符串Java 什么更有效:replaceFirst()或带有锚定正则表达式的replaceAll()?,java,regex,performance,Java,Regex,Performance,我们有一个字符串string s=“first.second.third…n-1.n” 在Java中,两种正则表达式方法中哪一种更有效 s = s.replaceFirst(".*?\\.", ""); 或 他们做同样的事情,但我想知道哪一个更快 区别在于: 使用锚定正则表达式vs.replaceFirst()仅匹配第一个实例 使用非贪婪的*?与非点字符类[^.] 使用\\.文字与[.]字符类 我更喜欢一个答案,它将基准测试或解释这些单独的性能影响。第二个regexp更有效,因为它不会回溯 下
string s=“first.second.third…n-1.n”代码>
在Java中,两种正则表达式方法中哪一种更有效
s = s.replaceFirst(".*?\\.", "");
或
他们做同样的事情,但我想知道哪一个更快
区别在于:
使用锚定正则表达式vs.replaceFirst()
仅匹配第一个实例
使用非贪婪的*?
与非点字符类[^.]
使用\\.
文字与[.]
字符类
我更喜欢一个答案,它将基准测试或解释这些单独的性能影响。第二个regexp更有效,因为它不会回溯
下面是一篇很好的文章,解释了细节。这篇文章解释了这个表达式是如何表达的
<.*?>
<[^>]*>
执行25个步骤,而表达式
<.*?>
<[^>]*>
]*>
在
字符串中查找匹配只需五个步骤,说明了正则表达式引擎生成匹配所需的每个步骤
\.
和[.]
之间应该没有区别-好的regexp引擎将两个子表达式转换为相同的编译表达式
带有replaceAll
的锚定版本与非锚定replaceFirst
的锚定版本做的事情不同,因为当点
是字符串中的第一个字符时,锚定版本将找不到匹配项。您可以通过将+
替换为*
来解决此问题
有了这个区别,replaceAll
将花更多的时间检查是否没有其他匹配项(因为表达式被锚定了,所以不会有其他匹配项),但这对于初始运行时间较长且不包含点的字符串来说并不重要。我没有访问javac的权限,因此无法进行基准测试。您提出的问题可能是指将锚定版本替换为replaceAll
,对吗?普通的replace
没有使用正则表达式。@dasblinkenlight,我继续并修复了它。这很好地解决了差异#2。与#1和#3有什么区别吗?请注意,replaceAll
根本不是关键。既然只进行了一次替换,为什么不将replaceFirst
与更高效的regexp一起使用呢s.replaceFirst(“^[^.]+\\”,”)
将完美运行,并且将是最快的(或者完全相同,因为锚点可用于优化replaceAll
)。@MarkoTopolnik结果将完全相同,但replaceFirst
将稍微快一点,因为不会再次调用Matcher
的find
方法。