TLDR: theString = theString.replace("\\", "\\\\");bunun yerine kullanın.
Sorun
replaceAll(target, replacement)için targetve kısmen için normal ifade (regex) sözdizimini kullanır replacement.
Sorun şu ki \, normal ifadede ( \dbasamağı 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ü targettemsil 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ı $xsağ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$1iki kopyasıyla değiştirecektir. (onu çoğaltacaktır) sonuçlanır "001122".
Öyleyse yine, kelimenin tam anlamıyla replacementtemsil 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 replacementtutmak 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 targetve replacementbö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 replacenormal ifade sözdizimini içermez. Böylece yazabilirsin
theString = theString.replace("\\", "\\\\");