TLDR: theString = theString.replace("\\", "\\\\");
bunun yerine kullanın.
Sorun
replaceAll(target, replacement)
için target
ve kısmen için normal ifade (regex) sözdizimini kullanır replacement
.
Sorun şu ki \
, normal ifadede ( \d
basamağı temsil ediyor gibi kullanılabilir ) ve Dize hazır "\n"
bilgisinde (satır ayırıcıyı temsil \"
etmek veya normalde dize değişmezinin sonunu temsil eden çift tırnak sembolünden kaçmak için kullanılabilir ).
Her iki durumda da \
sembol yaratmak için, önüne ilave koyarak ondan kaçabiliriz (onu özel karakter yerine değişmez hale getirebiliriz) \
(örneğin "
aracılığıyla dize değişmezlerinde kaçtığımız gibi \"
).
Dolayısıyla, sembolü target
temsil eden regex \
için tutulması gerekecek \\
ve böyle bir metni temsil eden dize değişmezinin benzemesi gerekecektir "\\\\"
.
Bu yüzden \
iki kez kaçtık :
- normal ifadede bir kez
\\
- String değişmezinde bir kez
"\\\\"
(her biri \
olarak temsil edilir "\\"
).
Olması durumunda replacement
\
da özeldir. Gösterim $
yoluyla diğer özel karakterlerden kaçmamızı $x
sağlar, normal ifade ile eşleşen ve indekslenmiş grup tarafından tutulan verilerin bir kısmını kullanmamıza izin verir x
, tıpkı "012".replaceAll("(\\d)", "$1$1")
her bir rakamla eşleşecek, onu yakalama grubu 1'e yerleştirecek ve $1$1
iki kopyasıyla değiştirecektir. (onu çoğaltacaktır) sonuçlanır "001122"
.
Öyleyse yine, kelimenin tam anlamıyla replacement
temsil edilmesine izin vermek \
için, ondan ek olarak kaçmamız gerekir, \
bu da şu anlama gelir:
- değiştirme iki ters eğik çizgi karakteri içermelidir
\\
- ve
\\
gibi görünen String değişmez değeri"\\\\"
AMA iki ters eğik çizgiyi replacement
tutmak istediğimiz için ihtiyacımız olacak (her biri bir ile temsil edilir )."\\\\\\\\"
\
"\\\\"
Böylece sürüm replaceAll
şuna benzeyebilir:
replaceAll("\\\\", "\\\\\\\\");
Daha kolay yol
Hayatı kolaylaştırmak için Java, metnin target
ve replacement
bölümlerin içine otomatik olarak kaçmak için araçlar sağlar . Artık yalnızca dizelere odaklanıp normal ifade sözdizimini unutabiliriz:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
bizim durumumuzda böyle görünebilir
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
Daha iyi
Regex sözdizimi desteğine gerçekten ihtiyacımız yoksa, hiç dahil etmemeye izin verelim replaceAll
. Bunun yerine kullanalım replace
. Her iki yöntem de tüm target
URL'lerin yerini alır , ancak replace
normal ifade sözdizimini içermez. Böylece yazabilirsin
theString = theString.replace("\\", "\\\\");