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
    方法。