2016-09-14 52 views
2

比方說,我有這樣的事情:有沒有辦法指定一個正則表達式不符合其他任何一個?

pattern = new Pattern[6]; 
    pattern[0] = Pattern.compile("^\\s*(NAME\\:\\s*)\\s(\\w+)"); 
    pattern[1] = Pattern.compile("^\\s*(AGE\\:\\s*)\\s(\\d+)"); 
    pattern[2] = Pattern.compile("^\\s*(ADDRESS\\:\\s)(\\w+)"); 
    pattern[3] = Pattern.compile("^\\s*(BIRTHDAY\\:\\s)(\\d+)\\:(\\d+)\\:(\\d+)");   
    pattern[4] = Pattern.compile("(?=\\s*\\*)(^\\**)"); 
    pattern[5] = Pattern.compile("\\S+|[^\\s*.+\\s*]"); 

模式4的點是捕獲的意見,然後*和模式5是捕捉一切,其他模式不能。然後Matcher dp將檢查該模式是否是從LookAhead返回true或false的預期模式。

public boolean lookAhead() { 
     while ((line = buff.readLine()) != null) { 
       Pattern different = Pattern.compile("^[^(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)]");     
       Matcher comment = pattern[4].matcher(line); 
       Matcher diff = different.matcher(line); 
       Matcher name = pattern[0].matcher(line); 
       if (comment.find() || different.find() /*|| name.find()*/)    
        continue; 
        Matcher dp = pattern[0].matcher(line); 
        dpla = dp.find(); 
        break; 
       } 
     } 
     return dpla; 
    } 

該評論被忽略,所有的隨機錯誤,如:「feifiejfie」也是。但是,如果文本類似「名稱7987997 GSGSGE 456」,則應將其視爲錯誤,但不是。如果name.find未註釋,它將始終有效,但不會返回false。

+1

也許你應該在也可以說你的輸入變量有多少**有效;以及你的代碼應該在做什麼。我很難從你的正則表達式中扣除這個邏輯。這已經給出了一點提示,說明你的當前代碼不太容易閱讀。意思是:我認爲這裏的解決方案是通過專注於你真正想知道的關於你的輸入的東西來大幅改進你的代碼。因此:請澄清您的要求。 – GhostCat

+0

'模式[4]'看起來不對我。它與「在輸入開始時的一個或多個星號相匹配」,並且大多數前瞻是毫無意義的;這相當於'「^ \\ * +」' – Bohemian

+0

備案:如果我的回答對你有幫助,請告訴我;或者如果有什麼遺漏...... – GhostCat

回答

2

我今天能夠解決問題!如果我沒有很好地解釋我的問題,我很抱歉,因爲我不得不做出更簡單的正則表達式來試圖解釋這個問題,也許我錯過了一些重要的觀點來得到一個好的答案。與我所擁有的相比,這是一段非常簡單的代碼。主要的問題是,雖然評論和一切不是模式(模式'錯誤'是否定所有以其他模式開始的東西)會被檢測到,並且如果模式以NAME:或AGE開始,將繼續While循環:等等,這意味着它將與'錯誤'模式不同,所以它不會繼續循環,但是這不應該發生,因爲它應該只在檢測到有效模式時停止循環。所以我做的是這樣的:

Pattern legit = Pattern.compile("^[(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)"); 
Matcher leg = legit.matcher(line); 

這種模式的要點是確定什麼是可能的情況下,評論和錯誤失敗。如果他們這樣做,他們需要檢查是否有效問卷失敗:

(leg.find() && (!name.find() && !age.find() && !addr.find() && !bd.find()))) 

您可以選擇的模式,你想通過在參數INT找到,它會改變這一點:

Matcher input = pattern[a].matcher(line); 
       if (!input.find() ...) 

所以一切結合會是這樣的:

public boolean lookAhead (int a) { 
     Pattern error = Pattern.compile("^[^(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)]"); 
     Pattern legit = Pattern.compile("^[(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)"); 
     while ((line = buff.readLine()) != null) {         
       Matcher comment = pattern[4].matcher(line); 
       Matcher err = error.matcher(line); 
       Matcher leg = legit.matcher(line); 
       Matcher name = pattern[0].matcher(line); 
       Matcher age = pattern[1].matcher(line); 
       Matcher addr = pattern[2].matcher(line); 
       Matcher bd = pattern[3].matcher(line); 
       Matcher input = pattern[a].matcher(line); 
       if (!input.find() && (comment.find() || err.find() || (leg.find() && (!name.find() && !age.find() && !addr.find() && !bd.find())))    
        continue; 
        Matcher dp = pattern[a].matcher(line); 
        dpla = dp.find(); 
        break; 
       } 
     } 
     return dpla; 
    } 

作品完全一樣,我想:d

2

讓我們乾脆採取一些不同的方法。實質上,我認爲你有一些輸入字符串;然後你有一個可能包含你感興趣的匹配器的不同正則表達式列表。你在代碼中做了很多匹配,最終只返回一個布爾值;這似乎沒有用;所以我會給你一個想法如何做不同的事情。

class RegexListMatcher { 
    private final Map<String, Pattern> patternsById; 
    private final String inputToMatchOn; 

    private final String matchingId; 
    private final String matchResult; 

    RegexListMatcher(Map<String, Pattern> patternsById, inputToMatchOn) { 
    this.patterns... = patterns 
    this.input... = input 

    matchingId = findMatchingId(); 
    if (matchingId == null) { 
     matchResult = null; 
    } else { 
     matchResult = getMatchResult(); 
    } 
    } 

    private final String findMatchingId() { 
    for (Entry<String, Pattern> entry : patternsById) { 
     if entry.value matches the given input return entry.key 

    otherwise return null 
    } 

    private final String getMatchResult() { 
    Pattern pattern = patternsById.get(matchingId); 
    return the value matched within input 
    } 

    public boolean hasMatch() { return matchingID != null; } 
    public String getMatchId() ... 
    public String getMatchResult() ... 

要等一起使用:

private final static Map<String, Pattern> RULES = new HashMap<>(); 
RULES.put("NAME", Pattern.compile("^\\s*(NAME\\:\\s*)\\s(\\w+)")); 
... 

RegexListMatcher listMatcher = new RegexListMatcher(RULES, someInputString); 
if (listMatcher.hasMatch()) { 
    one of the rules matched 
} else { 
    no match at all 
} 

我在執行關鍵的一點:你有潛在的模式列表;如果其中一項匹配,您肯定會對您的輸入中匹配的值感興趣。令人驚訝的是,如果沒有一種模式匹配,那麼你也知道這一點。因爲RegexListMatcher可以告訴你。

當然,比你更多的代碼;但是例如:根本沒有對某個數組索引進行任何硬編碼訪問。顯然,以上是部分僞代碼,但我想它應該足以讓你開始。

相關問題