2009-11-09 14 views
90

私はreplaceAllを使用してString\\something\\String\something\を変換しようとしているが、私はエラーのすべての種類を取得しておきます。ダブルバックスラッシュとString.replaceAll単一のバックスラッシュ

theString.replaceAll("\\", "\\\\"); 

しかし、これは、以下の例外ができます:あなたはそれが正規表現であるとして、最初の引数で(エスケープ)バックスラッシュをエスケープする必要があります

java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 

答えて

162

String#replaceAll()は、引数をregular expressionと解釈します。 \は、のエスケープ文字です。Stringregexです。あなたは正規表現のためにそれをダブルエスケープする必要があります。

string.replaceAll("\\\\", "\\\\\\\\"); 

しかし、あなたは、必ずしもあなたが正確な文字単位での交換をしたいとあなたがここにパターンを必要としないという理由だけで、このために正規表現を必要としません。だから、String#replace()で十分です:

string.replace("\\", "\\\\"); 

を更新:コメントごとに、あなたはJavaScriptのコンテキスト内の文字列を使用するように見えます。代わりに、より多くの文字をカバーする代わりにStringEscapeUtils#escapeEcmaScript()を使用するほうがよいでしょう。

+0

実際にはJavaScript ASTで使用されていますが、ソースに変換する必要があります。あなたのソリューションは機能します。ありがとう! –

+0

とにかく 'String#replaceAll()'を使用する場合は、[Matcher#quoteReplacement()](http://docs.oracle.com/javase/7/docs/api/java/)で置換文字列を引用できます( "\\"、\ "\\"、\ "\\"、\ "\\" \\\ ")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ –

6

を私はこれが解決策だと思いました。交換は、(第二引数 - Matcher#replaceAll(String)を参照)また、あなたがにそれらを交換する必要がありますので、それは、バックスラッシュの特別な意味ですがあります

theString.replaceAll("\\\\", "\\\\\\\\"); 
3

はい...時間によって正規表現コンパイラはあなたが与えてくれたのパターンを見ていますそれは、Javaのレクサーがダブルバックバックを単一のものにしているので、バックスラッシュは1つしか見えません。 "\\\\""\\\\"と置き換える必要があります。 Javaは本当に良い生の文字列構文を必要とします。

12

このような問題を回避するには、replaceAll(正規表現を使用)の代わりにreplace(プレーンストリングを使用)を使用できます。バックスラッシュをエスケープする必要がありますが、正規表現では必要とされません。

4

replaceAll(target, replacement)は、targetの正規表現(正規表現)を使用し、replacementの部分正規表現を使用します。

問題\は(二重引用符記号を表すために行セパレータまたは\"を作成するための\nのような)特別な正規表現の文字(のような\dには数字を表します)と文字列リテラルであり、我々はそれをエスケープする必要が\シンボルを作成することですこれらのレベルの前に追加の\が追加されています。リテラル"\\\\"は(各\は独自の余分な\前に必要)正規表現\\

  • 文字列に

    • だから私たちは二度それをエスケープする必要が\記号を表しますtarget正規表現を作成します。replacement\の場合

    $ある一つの他の特殊文字をエスケープすることが特別です。 $xという表記法では、正規表現にマッチしたデータの一部にアクセスして再利用することができます。replaceAll("(\d)", "$1$1")は各桁を複製します。

    • \\
    • が、文字列リテラル\\を表す"\\\\"

    のように見えるが、我々が望む以来:我々は2つのバックスラッシュを表すテキスト必要replacement単一\を持っているので、再び

    を2つ入れて\の代わりに"\\\\\\\\"が必要です("\\\\" 2個)。

    replaceAll("\\\\", "\\\\\\\\"); 
    

    Javaが自動的にtargetreplacementの部分にテキストをエスケープするためのツールを提供して生活がより簡単に作るために。だから今、私たちは、文字列にのみ焦点を当てて、正規表現の構文を忘れることができます。

    replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement)) 
    

    私たちが使用したくない場合は、当社の場合には

    replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\")) 
    

    あるいはさらに簡単のように見えることができましたregexはreplaceAllを含まず、代わりにreplaceを使用します(どちらの方法もすべてtargetに置き換えられますが、2番目の方法は正規表現の構文を伴わない)。あなたは簡単に書くことができます

    theString = theString.replace("\\", "\\\\") 
    
  • 関連する問題