【问题标题】:Fastest way to replace last occurrence of pattern in a string替换字符串中最后一次出现的模式的最快方法
【发布时间】:2015-03-28 04:00:37
【问题描述】:

在查看了有关替换最后一个单词的不同问题后,我没有找到涵盖最快方法的问题。在我的场景中,我想在一个句点之后替换字符串的最后一位,或者最后一个单词以及之后的所有内容。

为了更好地解释,这个方法完全按照我想要的方式替换了字符串:(编辑:我根据 Avinash 的响应更改了正则表达式,仍在寻找更快的替代方法,因为正则表达式替换仍然很慢)

return permission.replaceAll("\\w+(?:\\.\\*)?$", "*");

示例输入 -> 输出

test.test.test -> test.test.*
test.test.* -> test.*

虽然这可行,但我正在寻找一种更快的方法来实现相同的结果。这个方法经常被调用,它出现在我的 profiling cpu 结果的顶部。

【问题讨论】:

  • 哦不,我回答了你原来的问题。好的,如果有人回答,这是比"\\w+(?:\\.\\*)?$" 更快的方法,那么您将问题更改为“我根据这个正则表达式更改了我的正则表达式。我还在寻找更快的方法”?这不是正确的行为。还原您的编辑。并等待更多时间。有人可能会提供比我更胖的解决方案。
  • 您是否应该重用已编译的模式?如果正则表达式没有改变,则找到正则表达式模式并编译并重用它。

标签: java regex string replace replaceall


【解决方案1】:

将其发布为答案,因为它位于另一个答案的 cmets 中:

乔普·埃根的回答:

感谢您让我知道,永远不知道。正则表达式方式:当然是replaceFirst;并且不要忘记多次替换 private static final Pattern PATTERN = Pattern,compile("\w+(?:\.\*)?$"); ... s = PATTERN.matcher(s).replaceFirst("*");

证据:http://ideone.com/vsObMZ Pattern 被证明是迄今为止最快的方法,因此这将是公认的答案。

Pattern p = Pattern.compile("\\w+(?:\\.\\*)?$");
return p.matcher(permission).replaceFirst("*");

【讨论】:

    【解决方案2】:
    static String lastWord(String s) {
        if (s.endsWith(".*")) {
            s = s.substring(0, s.length() - 2);
        }
        int pos = s.lastIndexOf('.') + 1;
        return s.substring(0, pos) + '*';
    }
    

    正则表达式很慢。您可以使用Pattern.compile 来创建一个全局模式以加快速度,但这里不使用正则表达式更简单。

    【讨论】:

    • 这没有通过我上面发布的两个测试。当输入 test.test.* 你的代码应该输出 test.* 时会输出同样的东西。*
    • 好的,到目前为止这是最快的方法,不过我会等几天才能接受答案。
    • 感谢您让我知道,永远不知道。正则表达式方式:replaceFirst 当然;不要忘记多次替换private static final Pattern PATTERN = Pattern,compile("\\w+(?:\\.\\*)?$"); ... s = PATTERN.matcher(s).replaceFirst("*");
    • 在忘记这件事后,我终于回到了这个话题。您对正则表达式方式的评论似乎是最快的方法。 ideone.com/vsObMZ
    【解决方案3】:

    这里不需要交替运算符。将\\.\\* 放在\\w+ 之后的非捕获组中,并通过在该组旁边添加? 量词使其成为可选。如有必要,使用捕获组。也就是说,这种替换不需要捕获组来捕获稍后要引用的字符。这些修改必须减少处理时间。

    string.replaceAll("\\w+(?:\\.\\*)?$", "*");
    

    DEMO

    【讨论】:

    • 我这样做了,它对花费的时间没有显着影响。它确实降低了,但还不够。
    【解决方案4】:
    ^(.+\.(?=\w)).*
    

    试试这个。替换为$1*。查看演示。

    https://regex101.com/r/dW8mK5/7

    【讨论】:

      猜你喜欢
      • 2016-08-07
      • 2011-04-19
      • 2011-07-26
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      相关资源
      最近更新 更多