String.replaceすべての単一バックスラッシュと二重バックスラッシュ
-
19-09-2019 - |
質問
変換しようとしています String
\something\
に String
\\something\\
を使用して replaceAll
, しかし、あらゆる種類のエラーが発生し続けます。これが解決策だと思いました:
theString.replaceAll("\\", "\\\\");
ただし、これには以下の例外が発生します。
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
解決
の String#replaceAll()
引数を次のように解釈します 正規表現. 。の \
はエスケープ文字です 両方 String
そして regex
. 。正規表現の場合は 2 回エスケープする必要があります。
string.replaceAll("\\\\", "\\\\\\\\");
ただし、これには必ずしも正規表現が必要というわけではありません。単に文字ごとに正確に置換する必要があり、ここではパターンが必要ないからです。それで String#replace()
十分なはずです:
string.replace("\\", "\\\\");
アップデート:コメントによると、JavaScript コンテキストで文字列を使用したいようです。おそらく使ったほうがいいでしょう StringEscapeUtils#escapeEcmaScript()
代わりに、より多くのキャラクターをカバーします。
他のヒント
トラブルのこの種のを回避するには、(正規表現をとる)の代わりにreplace
の(プレーンな文字列を取り)replaceAll
を使用することができます。あなたはまだではなく、正規表現を必要と野生の方法で、バックスラッシュをエスケープする必要があります。
TLDR:使用 theString = theString.replace("\\", "\\\\");
その代わり。
問題
replaceAll(target, replacement)
正規表現 (regex) 構文を使用します target
そして部分的には replacement
.
問題はそれです \
正規表現の特殊文字です (次のように使用できます) \d
to は数字を表します) および文字列リテラル (次のように使用できます) "\n"
行区切り文字を表すか、 \"
通常は文字列リテラルの終わりを表す二重引用符をエスケープします)。
どちらの場合も作成するには \
私たちにできることの象徴 逃げる 追加の文字を配置して (特殊文字ではなくリテラルにします) \
その前に(逃げるように) "
文字列リテラルで \"
).
する target
正規表現を表す \
シンボルを保持する必要があります \\
, 、そのようなテキストを表す文字列リテラルは次のようにする必要があります。 "\\\\"
.
それで私たちは逃げ出した \
2回:
- 正規表現で 1 回
\\
- 文字列リテラルに一度
"\\\\"
(それぞれ\
として表されます"\\"
).
の場合には replacement
\
そこも特別です。他の特殊文字をエスケープできるようになります $
どの経由で $x
この表記法を使用すると、正規表現に一致し、次のようにインデックス付けされたグループをキャプチャすることによって保持されるデータの一部を使用できます。 x
, 、 のように "012".replaceAll("(\\d)", "$1$1")
各数字と一致し、それをキャプチャ グループ 1 に配置し、 $1$1
それを 2 つのコピーで置き換えます (複製します)。 "001122"
.
それで、もう一度、させてください replacement
代表する \
リテラルでは追加でエスケープする必要があります \
これは次のことを意味します:
- 置換には 2 つのバックスラッシュ文字を含める必要があります
\\
- およびそれを表す文字列リテラル
\\
のように見える"\\\\"
でも、私たちが望んでいるから replacement
保持する 二 バックスラッシュが必要になります "\\\\\\\\"
(それぞれ \
一つで表される "\\\\"
).
したがって、バージョン replaceAll
のように見えることができます
replaceAll("\\\\", "\\\\\\\\");
より簡単な方法
作業を容易にするために、Java はテキストを自動的にエスケープするツールを提供します。 target
そして replacement
部品。したがって、今度は文字列のみに焦点を当て、正規表現構文のことは忘れることができます。
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
私たちの場合は次のようになります
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
さらに良い
正規表現構文のサポートが本当に必要ない場合は、関与しないようにしましょう replaceAll
全然。代わりに使用しましょう replace
. 。どちらの方法でも置き換えられます 全て target
ですが、 replace
正規表現構文は含まれません。したがって、単純に書くことができます
theString = theString.replace("\\", "\\\\");
あなたは、最初の引数で(エスケープ)バックスラッシュをエスケープする必要があります。交換(第二引数 - <のhref =参照 "http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Matcher.html#replaceAll(java.lang.String)" REL = "noreferrer">のMatcher#でReplaceAll(String)をを)また、あなたがにそれらを交換する必要がありますので、それは、バックスラッシュの特別な意味だあります:
theString.replaceAll("\\\\", "\\\\\\\\");
はい、それは、単一のバックスラッシュを見ています。あなたが"\\\\"
で"\\\\"
を交換する必要がない、またはそれを信じて! Javaは本当に良い生の文字列構文を必要とします。