2011-04-07 269 views
2

考慮下面的代碼:避免代碼重複

if (matcher1.find()) { 
    String str = line.substring(matcher1.start()+7,matcher1.end()-1); 
    /*+7 and -1 indicate the prefix and suffix of the matcher... */  
    method1(str); 
} 
if (matcher2.find()) { 
    String str = line.substring(matcher2.start()+8,matcher2.end()-1); 
    method2(str); 
} 
... 

我有n個的匹配,匹配器全部是獨立的(如果是真的,它沒有提到其他人......),用於這是真正的每個匹配 - 我對其匹配的內容調用了不同的方法。
問題:我不喜歡這裏的代碼重複或「魔術數字」,但我想知道是否有更好的方法來做到這一點......? (也許遊客模式?)有什麼建議嗎?

+0

如果它們是獨立的,則應該能夠製作大正則表達式並使用http://download.oracle.com/javase/tutorial/essential/regex/groups.html遍歷子字符串。 – helpermethod 2011-04-07 08:23:24

+1

@Helper:404在你的鏈接上,「to」連接到.html – amit 2011-04-07 08:27:52

+0

http://download.oracle.com/javase/tutorial/essential/regex/groups.html – helpermethod 2011-04-07 08:53:39

回答

4

創建一個抽象類,並在子類中添加偏移量(也可以根據您的要求使用字符串處理...)。

然後將它們填充到列表中並處理列表。

這裏是一個示例absract處理器:

public abstract class AbsractProcessor { 

    public void find(Pattern pattern, String line) { 
     Matcher matcher = p.matcher(line); 
     if (matcher.find()) { 
      process(line.substring(matcher.start() + getStartOffset(), matcher.end() - getEndOffset())); 
     } 
    } 

    protected abstract int getStartOffset(); 

    protected abstract int getEndOffset(); 

    protected abstract void process(String str); 

} 
+0

看起來很優雅,我還在想如果對於我的情況來說,這並不算太多(有點像用大炮捕捉蝴蝶)+1,無論如何,對於優雅。 – amit 2011-04-07 08:37:37

+0

這似乎太多了,因爲Java太冗長了,會更加優雅,像Scala或Python這樣具有功能風格的語言。 – 2011-04-07 08:46:46

+1

但我的一個黃金法則是:永遠不要重複任何代碼...或者你會多次糾正相同的錯誤(或忘記......)。這是抽象的力量......恕我直言,這就是讓你成爲一名優秀程序員的原因。順便說一句,接受答案,如果它是可以的;) – 2011-04-07 08:47:49

0

你可以把它一點點短,但我的問題是,這真的值得去努力:

private String getStringFromMatcher(Matcher matcher, int magicNumber) { 
    return line.subString(matcher.start() + magicNumber, matcher.end() - 1) 
} 

if (matcher1.find()) { 
method1(getStringFromMatcher(matcher1, 7); 
} 

if (matcher2.find()) { 
method2.(getStringFromMatcher(mather2, 8); 
} 
0

使用Cochard的解決方案結合使用所有methodX方法的工廠(switch語句)。所以你可以這樣調用:

Factory.CallMethodX(myEnum.MethodX, str) 

您可以在Cochard的解決方案

1

簡單的標誌,你想傳遞給了該方法的正則表達式的一部分人口步分配myEnum.MethodX捕獲組。

例如,如果你的正則表達式是foo.*bar,你不感興趣的foobar,使正則表達式foo(.*)bar。然後總是從Matcher抓住組1。然後

您的代碼應該是這樣的:

method1(matcher1.group(1)); 
method2(matcher2.group(2)); 
... 

一個進一步的步驟將是使用類實現一個這樣的更換你的方法:

public interface MatchingMethod { 
    String getRegex(); 
    void apply(String result); 
} 

然後你就可以輕鬆地自動執行該任務:

for (MatchingMethod mm : getAllMatchingMethods()) { 
    Pattern p = Pattern.compile(mm.getRegex()); 
    Matcher m = p.matcher(input); 
    while (m.find()) { 
    mm.apply(m.group(1)); 
} 

請注意,如果性能很重要,那麼預編譯如果將此應用於許多輸入,則Pattern可以改善運行時。

+0

+1使用捕獲組,這清理了很多。 – 2011-04-07 08:48:58