2011-04-07 220 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