簡體   English   中英

Java Regex需要太長時間

[英]Java Regex takes too long

我有這個正則表達式

"((\\\\s{0,2})\\\\p{XDigit}{2}\\\\s{0,2})*"

用戶可以像這樣從字節轉儲中選擇匹配的字符串 在此輸入圖像描述

上面的選擇應該是可能的,但選擇一半的字節不應該這樣 在此輸入圖像描述

最后或開頭的空格不應該是這樣的問題 在此輸入圖像描述

給定正則表達式的問題是匹配需要太長時間。 我能改進什么,問題是什么?

編輯:

所以我為這個案例建立了一個解決方案。 我唯一需要檢查的是字符串的開頭和結尾。 刪除空格並檢查分割字符串的第一個和最后一個元素長度是否為1.我無論如何都要拆分它,因為之后我將它解析為一個字節數組。

        String selection = dumpText.getSelectionText();

        if (selection.equals(" ") || selection.equals("  ")){
            return;
        }

        //remove spaces at the beginning
        while(selection.charAt(0) == ' '){
            selection = selection.substring(1);
        }

        //remove spaces at the end
        while(selection.charAt(selection.length()-1) == ' '){
            selection = selection.substring(0, selection.length()-1);
        }

        String[] splitted = selection.split("\\s{1,2}");

        if(splitted.length == 0 || splitted[0].length()==1 || splitted[splitted.length-1].length()==1){
                return;
        }

當你問一些簡單的東西時,基本的字符串比較會更有效率。 在這種情況下,您只對前2個和后2個字符感興趣。

所以你只能測試那些(在驗證長度之后):

s.charAt(0) != ' ' && s.charAt(1) == ' ' 
    && s.charAt(s.length - 1) != ' ' && s.charAt(s.length - 2) == ' '

雖然這不是很花哨,但它會非常快。 你只是測試你是否有一個角色然后是一個空格,最后是另一種方式。

這僅適用於基本驗證。

試試這種模式:

\s{0,2}(?:\p{XDigit}{2}\s{0,2})*

您正在經歷災難性的回溯 ,在這種情況下(在這種情況下)您有多種方法無法匹配字符串。
我寫的模式基本相同,但應該只有一種方法匹配選擇:

  • \\s{0,2} - 可選的前導空格
  • (?:\\p{XDigit}{2}\\s{0,2})* - 一個或多個十六進制對,后面有空格。

請注意,此模式可以匹配沒有空格的十六進制數字,如12AB ,但無論如何它應該適用於您的用例。

另一個解決方案,只需檢查是否有任何單個字符被空格包圍。

/^([a-zA-Z0-9]\s+)|(\s+[a-zA-Z0-9]\s+)|(\s+[a-zA-Z0-9])$/gm

或類似的東西,以便在序列的開頭或結尾匹配單個字符

/^([a-zA-Z0-9]\s+)|(\s+[a-zA-Z0-9])$/gm

或者這個,它只返回兩個字符出現

/(?:\s*)([a-zA-Z0-9]{2})(?:\s*)/gm

演示1 | 演示 | 演示3

附注:在這種情況下,您可以使用\\p{XDigit}代替[a-za-z0-9]

我實際上不會嘗試匹配前面或尾隨空格,並使用單詞邊界保持正則表達式這么簡單:

\\b\\p{XDigit}{2}\\b

Matcher#find使用此正則表達式Matcher#find單獨匹配每個字節序列。

- RegEx演示

暫無
暫無

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

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