考虑以下代码:
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 :(得分:4)
创建一个抽象类,并在子类中添加偏移量(也可以根据需要使用字符串处理)。
然后在列表中填充它们并处理列表。
这是一个示例抽象处理器:
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);
}
答案 1 :(得分:1)
简单标记要传递给具有捕获组的方法的正则表达式部分。
例如,如果您的正则表达式为foo.*bar
且您对foo
或bar
不感兴趣,请制作正则表达式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
可以改善运行时。
答案 2 :(得分: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);
}
答案 3 :(得分:0)
将Cochard的解决方案与工厂(switch语句)结合使用,并使用所有方法X方法。所以你可以这样称呼它:
Factory.CallMethodX(myEnum.MethodX, str)
你可以在Cochard的解决方案的人口步骤中分配myEnum.MethodX