4

何らかの理由で、この Java コードの一部が重複する一致を示しています。

Pattern pat = Pattern.compile("(" + leftContext + ")" + ".*" + "(" + rightContext + ")", Pattern.DOTALL);

オーバーラップの検出を回避する方法/オプションはありますか? 例: leftContext rightContext rightContext は 2 ではなく 1 つの一致にする必要があります

完全なコードは次のとおりです。

public static String replaceWithContext(String input, String leftContext, String rightContext, String newString){   
  Pattern pat = Pattern.compile("(" + leftContext + ")" + ".*" + "(" + rightContext + ")", Pattern.DOTALL);
  Matcher matcher = pat.matcher(input);
  StringBuffer buffer = new StringBuffer();

  while (matcher.find()) { 
   matcher.appendReplacement(buffer, "");
   buffer.append(matcher.group(1) + newString + matcher.group(2));
  }
  matcher.appendTail(buffer);

  return buffer.toString();
 }

だからここに否定的な先読みを使った最終的な答えがあります.

Pattern pat = Pattern.compile("(" +
    leftContext + ")" + "(?:(?!" +
    rightContext + ").)*" + "(" +
    rightContext + ")", Pattern.DOTALL);
4

2 に答える 2

2

「重複」という言葉の使用は混乱を招きます。どうやら、あなたが意味したのは、正規表現が貪欲すぎて、最初leftContextから最後まですべてに一致するということでしたrightContext。あなたはすでにそれを理解していて、より良いアプローチも思いついたようですが、少なくとも 1 つの潜在的な問題が残っています。

あなたは「プレーンな文字列」leftContextと言いrightContextました。これは、正規表現として解釈されることは想定されていないことを意味していると思いますが、そうなるでしょう。それらをエスケープする必要があります。そうしないと、それらに含まれる正規表現のメタ文字によって、正しくない結果または実行時例外が発生します。同じことが置換文字列にも$当てはまりますが、バックスラッシュだけが特別な意味を持っています。以下に例を示します (貪欲.*?ではないことに注意してください)。

public static String replaceWithContext(String input, String leftContext, String rightContext, String newString){
  String lcRegex = Pattern.quote(leftContext);
  String rcRegex = Pattern.quote(rightContext);
  String replace = Matcher.quoteReplacment(newString);
  Pattern pat = Pattern.compile("(" + lcRegex + ").*?(" + rcRegex + ")", Pattern.DOTALL);

もう 1 つ: 一致したテキストに対して一致後の処理を行っていない場合は、 and を使用して独自にローリングする代わりに使用できreplaceAllます。appendReplacementappendTail

return input.replaceAll("(?s)(" + lcRegex + ")" +
                        "(?:(?!" + rcRegex + ").)*" +
                        "(" + rcRegex + ")",
    "$1" + replace + "$2");
于 2010-11-29T21:40:44.453 に答える
1

本当に必要なものに応じて、可能性はほとんどありません。

$次のように、正規表現の最後に追加できます。

"(" + leftContext + ")" + ".*" + "(" + rightContext + ")$"

最後のものでなければrightContext、正規表現は一致しません。

次に、以降のすべてをキャプチャできますrightContext

"(" + leftContext + ")" + ".*" + "(" + rightContext + ")(.*)"

その後、3 番目に一致するグループのすべてを破棄します。

しかし、私たちは何が何であるかを知らないのでleftContextrightContextおそらくあなたの問題はそれらの中にあります.

于 2010-11-27T08:57:41.923 に答える