をusing に変換しようとしていますString
\something\
が、あらゆる種類のエラーが発生し続けます。これが解決策だと思いました:String
\\something\\
replaceAll
theString.replaceAll("\\", "\\\\");
しかし、これは以下の例外を与えます:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
をusing に変換しようとしていますString
\something\
が、あらゆる種類のエラーが発生し続けます。これが解決策だと思いました:String
\\something\\
replaceAll
theString.replaceAll("\\", "\\\\");
しかし、これは以下の例外を与えます:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
回答:
String#replaceAll()
引数を解釈する正規表現を。\
でエスケープ文字で両方 String
とregex
。あなたは正規表現のためにそれをダブルエスケープする必要があります:
string.replaceAll("\\\\", "\\\\\\\\");
しかし、これは必ずしも正規表現を必要としません。正確な文字ごとの置換が必要であり、ここでパターンを必要としないからです。それでString#replace()
十分です:
string.replace("\\", "\\\\");
更新:コメントに従って、JavaScriptコンテキストで文字列を使用したいようです。StringEscapeUtils#escapeEcmaScript()
代わりに、より多くのキャラクターをカバーするために使用する方がよいでしょう。
String#replaceAll()
、とにかく、あなたはとの置換文字列を引用できるのMatcher#quoteReplacement() :theString.replaceAll("\\", Matcher.quoteReplacement("\\\\"));
この種の問題を回避するreplace
には、replaceAll
(正規表現を使用する)の代わりに(プレーンな文字列を使用する)を使用できます。引き続きバックスラッシュをエスケープする必要がありますが、正規表現で必要とされるワイルドな方法ではありません。
TLDR:theString = theString.replace("\\", "\\\\");
代わりに使用してください。
replaceAll(target, replacement)
では正規表現(regex)構文をtarget
部分的に使用していreplacement
ます。
問題は\
、正規表現(\d
数字を表すのに使用できる)や文字列リテラル(通常、文字列リテラルの終わり"\n"
を表す行区切り文字や\"
二重引用符をエスケープするのに使用できる)の特殊文字です。
これらのどちらの場合でも、\
シンボルを作成するために、その前に追加を配置することで(特殊文字の代わりにリテラルにする)シンボルをエスケープできます\
("
文字列リテラルでを介してエスケープするように\"
)。
したがって、シンボルをtarget
表す正規表現は\
保持する必要があり\\
、そのようなテキストを表す文字列リテラルは次のようにする必要があります"\\\\"
。
したがって、\
2回エスケープしました。
\\
"\\\\"
(それぞれ\
として表されます"\\"
)。replacement
\
特別な場合もございます。それは、私たちは、他の特殊文字エスケープすることができます$
経由で$x
の表記、私たちは、データの一部が正規表現にマッチしたとしてインデックス付けキャプチャグループが保有する使用することができますx
ように、"012".replaceAll("(\\d)", "$1$1")
グループ1の捕捉に各桁と一致します、場所、それをし、$1$1
その2回のコピーと交換します(それは複製されます)結果はになり"001122"
ます。
繰り返しますが、リテラルをreplacement
表す\
には、追加\
でエスケープする必要があります。つまり、
\\
\\
のようなルックスを"\\\\"
しかし、必要な2つのバックスラッシュをreplacement
保持したいので(それぞれ1で表されます)。"\\\\\\\\"
\
"\\\\"
のバージョンreplaceAll
は次のようになります
replaceAll("\\\\", "\\\\\\\\");
人生は簡単にアウトにするためにJavaは自動的にテキストをエスケープするためのツールを提供target
し、replacement
部品を。これで、文字列のみに焦点を当てることができ、正規表現の構文を忘れることができます。
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
私たちの場合は次のようになります
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
正規表現構文のサポートが本当に必要ない場合はreplaceAll
、一切関与させません。代わりにを使用できますreplace
。どちらの方法でもすべて target
のが置き換えられますがreplace
、正規表現構文は含まれません。だからあなたは単に書くことができます
theString = theString.replace("\\", "\\\\");
これは正規表現なので、最初の引数で(エスケープされた)バックスラッシュをエスケープする必要があります。置換(2番目の引数-Matcher#replaceAll(String)を参照)にもバックスラッシュの特別な意味があるため、これらを次のように置き換える必要があります。
theString.replaceAll("\\\\", "\\\\\\\\");
はい...正規表現コンパイラが指定したパターンを認識するまでに、バックスラッシュは1つしか見えません(Javaのレクサーが2つのバックスラックを1つに変換したため)。あなたは交換する必要がある"\\\\"
と"\\\\"
、それを信じるかどうか!Javaは本当に良い生の文字列構文を必要とします。