2015-10-30 7 views
7

{または}という文字列を含むと、正規表現の処理中に拒否されるようです。"リテラル"ではない文字列のメタキャラクタを常にエスケープする必要はありますか?

string.replaceAll("\\" + pattern); 

これは動作しますが、pattern{で始まる任意の文字列です:私は、これらの予約文字であり、私は私がしなければので、それらをエスケープする必要があることを理解することができます。

質問:このような問題を回避し、自動的に処理されるようなメタ文字を含む文字列でこのような問題を回避する方法はありますか?それはすでにあなたは定期的にで使用されるメタ文字をエスケープする

java.util.regex.Pattern.quote(java.lang.String) 

を使用することができ、二重引用符

+2

は、 'replaceAll'の代わりに' replace'を使います。 – Pshemo

+0

@Pshemo:彼らの行動は異なっていますか? – Jim

+0

ドキュメントを読む... 'replace(char、char)'と 'replace(String、String)'があります。 – Pshemo

答えて

4

を持っている文字列を入力として受け入れて対リテラル文字列に二重引用符を追加することと同じである必要があります私には思えます表現。

8

使用Pattern.quote(String)

public static String quote(String s) 

は、指定StringのリテラルパターンStringを返します。

Stringこのメソッドは、文字列sの文字列と同じようにPatternを作成するために使用することができるStringを生成します。

入力シーケンスのメタキャラクタまたはエスケープシーケンスには特別な意味はありません。

パラメータ:
        sから
戻りliteralizedする文字列:ので
       リテラル文字列置換
を:
        1.5

3

TL; DR

  • あなたが正規表現構文を使用replaceAllまたはreplaceFirstが必要な場合は、
  • あなたはリテラルがreplaceを使用すると、あなたのtarget/replacementペアが扱われることを望むならば(それはまたを置き換えますすべてあなたのターゲットのオカレンス)。

ほとんどの人がしているStringクラスのメソッドを置き換えるの不幸な命名で混乱している:

  • replaceAll(String, String)
  • replaceFirst(String, String)
  • replace(CharSequence, CharSequence)
  • replace(char, char)

replaceAll方法が明示的にそれがすべてかのうターゲットを置き換えることを主張しているので、人々はそれがAllサフィックスが含まれていないので、replace方法は、このような動作を保証するものではありませんしないことを前提としています。
しかし、この仮定は間違っています。これらの方法の間

主な違いは、この表に示されている:

╔═════════════════════╦═══════════════════════════════════════════════════════════════════╗ 
║      ║        replaced targets      ║ 
║      ╠════════════════════════════════════╦══════════════════════════════╣ 
║      ║   ALL found    ║  ONLY FIRST found  ║ 
╠══════╦══════════════╬════════════════════════════════════╬══════════════════════════════╣ 
║  ║ supported ║ replaceAll(String, String)   ║ replaceFirst(String, String) ║ 
║regex ╠══════════════╬════════════════════════════════════╬══════════════════════════════╣ 
║syntax║  not  ║ replace(CharSequence, CharSequence)║    \/    ║ 
║  ║ supported ║ replace(char, char)    ║    /\    ║ 
╚══════╩══════════════╩════════════════════════════════════╩══════════════════════════════╝ 

今、あなたはそれを期待していない正規表現構文の使用方法を使用する必要はありませんが、それはtargetreplacementを扱う場合リテラルとして。

ので、代わりのreplaceAll(regex, replacement)

使用replace(literal, replacement)


ご覧のとおり、replaceの2つのオーバーロードされたバージョンがあります。彼らは正規表現の構文をサポートしていないので、両方ともあなたのために働くはずです。

    • replace(char target, char replacement)は、単に新しい文字列を作成し、(文字をターゲットに等しかった場合によっては)それはどちらかの元の文字列から文字、または文字で、あなたが代替として決め埋める:それらの間の主な違いは、ということですreplace(CharSequence target, CharSequence replacement)は がreplaceAllと同じであることを意味するreplaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement.toString())の本質的に同等であるが、(意味し、それは内部で正規表現エンジンを使用)が、はそれが自動的に私たちのためtargetreplacementで使用される正規表現のメタ文字をエスケープ

  • +0

    @downvoterこの回答で何が間違っているかを気にして、改善することができますか? – Pshemo

    +0

    ニースの情報は、私が深く徹底的にJava正規表現を学びたいと思ったら、どのような資料をお勧めしますか? :) – Muhammad

    +1

    @Muhammad http://www.regular-expressions.info/tutorial.htmlは最高のチュートリアルです。純粋な正規表現と、さまざまな言語で実装されたその味の大部分について私はこれまでに発見しました。 Java正規表現のチュートリアルはhttps://docs.oracle.com/javase/tutorial/essential/regex/でも有益ですが、パターン・クラスhttps://docs.oracle.com/javase/8/docs/apiのドキュメントもお読みください。 /java/util/regex/Pattern.htmlには、Javaでどの正規表現メカニズムがサポートされているかに関する多くの情報が含まれています。 – Pshemo

    0

    Java's Pattern classに記載されているようにあなたは、余分なコードだけ\Q\E構造を必要としません。

    たとえば、次のコードで:

    String foobar = "crazyPassword=f()[email protected]{}+"; 
    Pattern regex = Pattern.compile("\\Q" + foobar "\\E"); 
    

    パターンコンパイルなり、foobarというの特殊文字は、正規表現文字として解釈されないであろう。デモhereを参照してください。

    唯一一致しないことは、入力にリテラル\Eが含まれていることです。あなたもその問題を解決する必要がある場合は、私はコメントで私に知らせて、私はそれを追加するために編集します。

    関連する問題