java - 正则表达式花费太多时间

标签 java regex performance

我在 Java 代码中有以下正则表达式,在某些情况下需要花费大量时间才能完成。有什么办法可以改善吗?

String decimal = "([0-9]+(\\.[0-9]+)?[/-]?)+";
String units = "(in|ft)\\.?";
String unitName = "(cu\\.? *ft|gauge|watt|rpm|ft|lbs|K|GPF|btu|mph|cfm|volt|oz|pounds|dbi|miles|amp|hour|kw|f|degrees|year)";

    sizePattern.add(Pattern.compile("(?i)" + decimal + " *" + units + " *x? *" + decimal + " *" + units + " *x? *" + decimal + " *" + units + ""));
    sizePattern.add(Pattern.compile("(?i)" + decimal + " *" + units + " *x? *" + decimal + " *" + units));
    sizePattern.add(Pattern.compile("(?i)" + decimal + " *x *" + decimal + " *" + units));
    sizePattern.add(Pattern.compile("(?i)" + decimal + "( *" + units + ")"));
    sizePattern.add(Pattern.compile("(?i)" + decimal + "( *sq?\\.?)( *ft?\\.?)"));
    sizePattern.add(Pattern.compile("(?i)" + decimal + " *" + unitName));
    sizePattern.add(Pattern.compile("(?i)" + decimal + "(d)"));
    sizePattern.add(Pattern.compile("(?i)" + decimal + "( *(%|percent))"));
    sizePattern.add(Pattern.compile("(?i)" + decimal));

    for (Pattern p : sizePattern)
    {
        ODebug.Write(Level.FINER, "PRD-0079: Using pattern = " + p.pattern());

        m = p.matcher(_data);
        while (m.find()) 
        {
            ODebug.Write(Level.FINER, "           Got => [" + m.group(0) + "]");
            this.Dimensions.add(m.group(0));

            _data = _data.replaceAll("\\Q" + m.group(0) + "\\E", ".");
            m = p.matcher(_data);
        }
    }

导致问题的字符串:

微感应炉灶提供最佳的炉灶性能、安全性和效率。当电流流过线圈时,感应加热,在陶瓷板下方产生磁场。当铁磁炊具放置在陶瓷表面时,炊具中会感应出电流,并且由于锅的电阻而瞬间产生热量。仅向锅产生热量,没有热量损失。由于没有明火,感应式燃烧器比传统燃烧器使用起来更安全。一旦取出炊具,所有分子 Activity 都会停止,加热也会立即停止。嵌入式或独立应用的冲洗表面双重功能: cooking 和保温7 功率设置 (100-300-500-700-900-1100-1300W)* 2 个最低功率设置功率设置无法实际实现,而是“模拟”:100W = 500W 间歇加热 2 秒,停止 8 秒 300W = 500W 间歇加热 6 秒,停止 4 秒 13 保温设置(100-120-140- 160-180-190-210-230-250-280-300-350-390F)带控制锁的触摸感应面板长达 8 小时定时器微晶陶瓷板自动锅检测LED 面板ETL/ETL-卫生/FCC 认证,适合家用或商业用途Home Depot保护计划:

最佳答案

假设你的_data很长,那么花费时间的不是匹配,而是赋值

_data = _data.replaceAll("\\Q" + m.group(0) + "\\E", ".");

就字符串长度而言,其复杂度为O(n**2)。只是不要这样做。

你可以用它来更简单

_data = _data.replace(m.group(0), ".");

但是不要这样做。最后需要减少 _data 吗?如果是这样,请为每个模式使用一个 replaceAll (它在内部使用 StringBuffer 并且仅与字符串的大小成线性关系)。

另外:

  • 使用非捕获组。
  • 考虑使用 reset(CharSequence)usePattern(Pattern) 回收 Matcher
  • 考虑将所有模式合并为一个。由于它们都以相同的方式开始,因此效率可能相当高。
  • 如果没有匹配项,您的小数可能会变慢。省略可选部分,您会得到 "([0-9]+)+" ,它可以不必要地回溯很多。考虑使用原子组。

关于java - 正则表达式花费太多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35220665/

相关文章:

python - 如何在Python中使用正则表达式删除字母并提取数字?

python - fast python numpy 哪里有功能?

java - 使用 robolectric 我的 expectedIntent 在不应该的时候为空

java - 如何从 Java 中的输入文本中删除标点符号?

r - 如何使用 POS 标记的正则表达式提取字符串

python - Tornado URL 正则表达式模式

java - Ormlite H2 从类分配数据时出错

java - 如何访问 JMonkeyEngine3 中 BetterCharacterControl 对象的 Vector3f 位置?

java - HQL 和连接——更快的方法?

android - hasOverlappingRendering() 和两个 ImageView