You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化匹配包含London与Paris顺序的正则表达式?

优化包含指定单词序列的正则表达式效率

你的思路完全没问题——当前正则确实能满足"字符串必须包含London且出现在Paris之前"的要求,但效率偏低的原因主要是两个点:[\w\W]*的冗余写法,以及贪婪匹配带来的潜在回溯开销。下面给你几个优化方案,既保证功能不变,又能提升效率:

方案一:简化正则表达式写法

[\w\W]*的作用是匹配任意字符(包括换行),但这种写法非常冗余,正则引擎需要额外判断字符是否属于\w或\W,反而不如更简洁的写法高效:

  • 如果你的字符串不会包含换行符,直接用.代替[\w\W],因为.默认匹配除换行外的所有字符,写法更简洁,引擎处理更快:
    String regexp = ".*London.*Paris.*";
    
  • 如果需要支持换行符,可以启用Pattern.DOTALL标志(让.匹配包括换行在内的所有字符),或者用[\s\S]*(匹配所有空白/非空白字符,等价于任意字符),推荐前者可读性更好:
    Pattern pattern = Pattern.compile(".*London.*Paris.*", Pattern.DOTALL);
    boolean t1 = pattern.matches(test1);
    

方案二:放弃正则,用原生字符串操作(效率更高)

正则引擎本身有一定的运行开销,如果你不需要复杂的正则匹配逻辑,直接用Java原生的字符串方法会更高效——我们只需要验证三个条件:包含London、包含Paris、且London的位置在Paris之前:

boolean containsSequence(String input) {
    int londonIdx = input.indexOf("London");
    int parisIdx = input.indexOf("Paris");
    return londonIdx != -1 && parisIdx != -1 && londonIdx < parisIdx;
}

// 调用示例
boolean t1 = containsSequence(test1);
boolean t2 = containsSequence(test2);
// ... 其他测试用例

这种方法是线性扫描字符串,没有正则的回溯开销,在字符串较长时优势尤其明显。

为什么原来的正则效率低?

[\w\W]*本质上是通过"匹配字母数字下划线"或"匹配非字母数字下划线"来覆盖所有字符,比直接用.多了一层判断逻辑;另外,贪婪模式的*在找不到目标字符串时,会不断回溯尝试匹配,虽然你的测试用例都能命中,但在更长的不满足条件的字符串中,会产生大量无效的回溯操作,拖慢执行速度。

内容的提问来源于stack exchange,提问作者NeverSleeps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:09:06