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個のマッチャーがあり、すべてのマッチャーは独立しています(1つが真の場合、他のマッチャーについては何も言いません...)、真のマッチャーごとに、一致したコンテンツに対して異なるメソッドを呼び出しています。
質問:ここにあるコードの重複や「魔法数」は好きではありませんが、それを行うためのより良い方法があるかどうか疑問に思っています...?(多分ビジターパターン?)何か提案はありますか?

4

4 に答える 4

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);

}
于 2011-04-07T08:22:28.847 に答える
1

メソッドに渡したい正規表現の部分をキャプチャ グループで簡単にマークします。

たとえば、正規表現がで、 orにfoo.*bar興味がない場合は、正規表現を にします。次に、常に からグループ 1 を取得します。foobarfoo(.*)barMatcher

コードは次のようになります。

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

もう 1 つのステップは、メソッドを次のように実装するクラスに置き換えることです。

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によって実行時間が改善されることに注意してください。

于 2011-04-07T08:28:23.720 に答える
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);
}
于 2011-04-07T08:24:52.220 に答える
0

すべての methodX メソッドを含むファクトリ (switch ステートメント) と組み合わせた Cochard のソリューションを使用します。次のように呼び出すことができます。

Factory.CallMethodX(myEnum.MethodX, str)

Cochardのソリューションの人口ステップで myEnum.MethodX を割り当てることができます

于 2011-04-07T08:28:06.363 に答える