2010-11-27 1 views
4

での正規表現のマッチングを重複しないでください?例えばは、Javaコードのこの作品は、試合を重ねる私を与えているいくつかの理由のJava

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

だからここに否定先読みを使用して、最終的な答えはだ、*は貪欲だった実現しませ用私の悪い:

leftContext rightContext rightContext はここで完全なコードがあります代わりに、2

の1が一致するべきです

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

leftContextとrightContextは何ですか?失敗した試合の例を教えてください。 – marcog

+1

正規表現マッチャーが重複するものを取得するのは、通常は少し難しい問題ですが、デフォルトでは起こりません。パターンの内容を見ることなく、何が起こっているのかを言うのは難しいです。マッチャーが文字列の同じ部分を2回以上通過するようにするには、基本的にルックアラウンドが必要です。あなたはそれをやっていますか? – tchrist

+0

rightContextとleftContextはプレーンな文字列です。e。g leftContext = "ab" rightContext = "cd" – Ricardo

答えて

2

「オーバーラップする」という言葉を混乱させます。どうやら、あなたが意味するのは、最初のleftContextから最後のrightContextまでのすべてを照合して、正規表現があまりにも貪欲であるということでした。あなたはすでにそれを理解しているようだが、よりよいアプローチを思いついたが、少なくとも1つの潜在的な問題はまだ残っている。

あなたはleftContextrightContextが「プレーンストリングス」だと言いましたが、正規表現として解釈されるべきではないということを意味していると思われますが、それらはそのままです。それらをエスケープする必要があります。そうしないと正規表現のメタキャラクタに不正な結果やランタイム例外が発生します。 $とバックスラッシュには特別な意味がありますが、置き換え文字列でも同様です。

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

もうひとつ:あなたはマッチしたテキストにどの試合後の処理を行っていない場合、あなたはreplaceAllの代わりに、独自のローリングを使用することができます。ここの例では、(あまりにも、非貪欲.*?に気づく)ですappendReplacementappendTail

return input.replaceAll("(?s)(" + lcRegex + ")" + 
         "(?:(?!" + rcRegex + ").)*" + 
         "(" + rcRegex + ")", 
    "$1" + replace + "$2"); 
1

本当に必要なものによっては、いくつかの可能性があります。

あなたはこのように、あなたの正規表現の末尾に$を追加することができますrightContextが最後のものでない場合は、お使いの正規表現が一致しなくなりますので

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

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

をし、その後、あなたの第三マッチンググループ内のすべてを捨てる:

次に、あなたはrightContext後、すべてをキャプチャすることができます。

しかし、leftContextrightContextが本当に何であるかわからないので、おそらくあなたの問題がその中にあるかもしれません。

+0

mm、それは私のコードで動作するかどうか、私は入力文字列の一部を破棄することはできません – Ricardo

関連する問題