Saya mencoba mengubahnya String
\something\
menjadi String
\\something\\
penggunaan replaceAll
, tetapi saya terus mendapatkan semua jenis kesalahan. Saya pikir inilah solusinya:
theString.replaceAll("\\", "\\\\");
Tetapi ini memberikan pengecualian di bawah ini:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
sumber
String#replaceAll()
, Anda dapat mengutip string pengganti dengan Matcher # quoteReplacement () :theString.replaceAll("\\", Matcher.quoteReplacement("\\\\"));
Untuk menghindari masalah seperti ini, Anda dapat menggunakan
replace
(yang menggunakan string biasa) daripadareplaceAll
(yang menggunakan ekspresi reguler). Anda masih perlu mengosongkan garis miring terbalik, tetapi tidak dengan cara liar yang diperlukan dengan ekspresi reguler.sumber
TLDR: gunakan
theString = theString.replace("\\", "\\\\");
saja.Masalah
replaceAll(target, replacement)
menggunakan sintaks ekspresi reguler (regex) untuktarget
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:\\
"\\\\"
(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:\\
\\
tampilannya"\\\\"
TAPI karena kami ingin
replacement
menahan dua garis miring terbalik, kami membutuhkan"\\\\\\\\"
(masing-masing\
diwakili oleh satu"\\\\"
).Jadi versi dengan
replaceAll
bisa terlihat sepertiCara yang lebih mudah
Untuk membuat hidup lebih mudah, Java menyediakan alat untuk secara otomatis memasukkan teks ke dalam
target
danreplacement
bagian. Jadi sekarang kita bisa fokus hanya pada string, dan lupakan sintaks regex:yang dalam kasus kita bisa terlihat seperti ini
Bahkan lebih baik
Jika kita tidak benar-benar membutuhkan dukungan sintaks regex, mari kita tidak terlibat
replaceAll
sama sekali. Sebaliknya mari kita gunakanreplace
. Kedua metode akan menggantikan semuatarget
s, tetapireplace
tidak melibatkan sintaks regex. Jadi Anda bisa langsung menulissumber
Anda harus melepaskan garis miring terbalik (escaped) di argumen pertama karena ini adalah ekspresi reguler. Penggantian (argumen ke-2 - lihat Matcher # replaceAll (String) ) juga memiliki arti khusus garis miring terbalik, jadi Anda harus menggantinya ke:
sumber
Ya ... pada saat regex compiler melihat pola yang Anda berikan, ia hanya melihat satu garis miring terbalik (karena lexer Java telah mengubah double backwhack menjadi satu). Anda perlu menggantinya
"\\\\"
dengan"\\\\"
, percaya atau tidak! Java sangat membutuhkan sintaks string mentah yang baik.sumber