TLDR: gunakan theString = theString.replace("\\", "\\\\");
saja.
Masalah
replaceAll(target, replacement)
menggunakan sintaks ekspresi reguler (regex) untuk target
dan sebagian untukreplacement
.
Masalahnya adalah \
karakter khusus dalam ekspresi reguler (dapat digunakan seperti \d
mewakili digit) dan dalam string literal (dapat digunakan seperti "\n"
untuk mewakili pemisah garis atau\"
untuk melepaskan simbol kutip ganda yang biasanya mewakili akhir string literal).
Dalam kedua kasus ini untuk membuat \
simbol, kita dapat menghindarinya (menjadikannya literal alih-alih karakter khusus) dengan menempatkan tambahan \
sebelum itu (seperti kita melarikan diri "
dalam literal string melalui \"
).
Jadi untuk target
ekspresi reguler, \
simbol perlu ditahan \\
, dan string literal yang mewakili teks seperti itu perlu terlihat "\\\\"
.
Jadi kami lolos \
dua kali:
- sekali dalam regex
\\
- sekali dalam String literal
"\\\\"
(masing \
- masing direpresentasikan sebagai "\\"
).
Dalam hal replacement
\
juga ada yang istimewa. Ini memungkinkan kita untuk keluar dari karakter khusus lainnya $
yang melalui $x
notasi, memungkinkan kita untuk menggunakan bagian dari data yang cocok dengan regex dan dipegang dengan menangkap grup yang diindeks sebagaix
, seperti "012".replaceAll("(\\d)", "$1$1")
akan mencocokkan setiap digit, menempatkannya dalam menangkap grup 1 dan $1$1
akan menggantinya dengan dua salinannya (itu akan menduplikasinya) menghasilkan"001122"
.
Jadi sekali lagi, biarkan replacement
mewakili\
literal kita perlu menghindarinya dengan tambahan \
yang berarti:
- pengganti harus memiliki dua karakter garis miring terbalik
\\
- dan String literal yang merepresentasikan
\\
tampilannya"\\\\"
TAPI karena kami ingin replacement
menahan dua garis miring terbalik, kami membutuhkan "\\\\\\\\"
(masing-masing\
diwakili oleh satu"\\\\"
).
Jadi versi dengan replaceAll
bisa terlihat seperti
replaceAll("\\\\", "\\\\\\\\");
Cara yang lebih mudah
Untuk membuat hidup lebih mudah, Java menyediakan alat untuk secara otomatis memasukkan teks ke dalam target
dan replacement
bagian. Jadi sekarang kita bisa fokus hanya pada string, dan lupakan sintaks regex:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
yang dalam kasus kita bisa terlihat seperti ini
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
Bahkan lebih baik
Jika kita tidak benar-benar membutuhkan dukungan sintaks regex, mari kita tidak terlibat replaceAll
sama sekali. Sebaliknya mari kita gunakan replace
. Kedua metode akan menggantikan semua target
s, tetapi replace
tidak melibatkan sintaks regex. Jadi Anda bisa langsung menulis
theString = theString.replace("\\", "\\\\");