我在 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/