簡體   English   中英

正則表達式表達花費太多時間

[英]Regex expression taking too much time

我在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);
        }
    }

導致問題的字符串:

微電磁爐灶具提供了最佳的灶具性能,安全性和效率。 電流流經線圈時感應發熱,從而在陶瓷板下方產生磁場。 當將鐵磁炊具放在陶瓷表面上時,炊具中會感應出電流,並且由於鍋的電阻會立即產生熱量。 鍋中僅產生熱量,沒有熱量損失。 由於沒有明火,因此感應器比常規燃燒器更安全。 移除炊具后,所有分子活動都會停止並立即停止加熱內置或獨立式應用的齊平表面雙重功能:Cook and Warm7功率設置(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認證的家用或商用家用倉庫保護計划:

假設您的_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
  • 考慮將所有模式組合為一個。 由於它們都是相同的,所以效率可能很高。
  • 萬一沒有匹配,您的decimal可能會變慢。 省略可選部分,您會得到"([0-9]+)+" ,它可以不必要地大量回退。 考慮使用原子團。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM