TLDR: ใช้theString = theString.replace("\\", "\\\\");แทน
ปัญหา
replaceAll(target, replacement)ใช้การแสดงออกปกติ (regex) ไวยากรณ์สำหรับและบางส่วน targetreplacement
ปัญหาคือ\อักขระพิเศษใน regex (สามารถใช้\dเพื่อแทนตัวเลข) และใน String literal (สามารถใช้"\n"เพื่อแสดงตัวคั่นบรรทัดหรือ\"เพื่อหลีกเลี่ยงสัญลักษณ์เครื่องหมายคำพูดคู่ซึ่งโดยปกติจะแสดงจุดสิ้นสุดของสตริงตามตัวอักษร)
ในทั้งสองกรณีนี้ในการสร้าง\สัญลักษณ์เราสามารถหลีกเลี่ยงมันได้ (ทำให้เป็นตัวอักษรแทนอักขระพิเศษ) โดยวางเพิ่มเติมไว้ข้าง\หน้า (เช่นเราหลบหนี"ในตัวอักษรสตริงผ่าน\")
ดังนั้นในการtargetregex ที่แสดง\สัญลักษณ์จะต้องมีค้างไว้\\และสตริงตามตัวอักษรที่แสดงข้อความดังกล่าวจะต้องมีลักษณะ"\\\\"ดังนี้
เราจึงหนี\สองครั้ง:
- ครั้งเดียวใน regex
\\
- หนึ่งครั้งใน String literal
"\\\\"(แต่ละตัว\จะแสดงเป็น"\\")
ในกรณีreplacement \พิเศษยังมี ช่วยให้เราสามารถหลีกเลี่ยงอักขระพิเศษอื่น ๆ$ซึ่งผ่าน$xสัญกรณ์ช่วยให้เราใช้ส่วนของข้อมูลที่จับคู่โดย regex และถือครองโดยการจับกลุ่มที่จัดทำดัชนีเนื่องจากxเหมือน"012".replaceAll("(\\d)", "$1$1")จะตรงกับแต่ละหลักวางไว้ในการจับกลุ่ม 1 และ$1$1จะแทนที่ด้วยสองสำเนา (มันจะซ้ำ) "001122"ที่เกิดขึ้นใน
ดังนั้นอีกครั้งเพื่อให้replacementเป็นตัวแทน\ตามตัวอักษรเราจำเป็นต้องหลีกเลี่ยงมันด้วยเพิ่มเติม\ซึ่งหมายความว่า:
- การแทนที่ต้องมีอักขระเครื่องหมายทับขวาสองตัว
\\
- และสตริงลิเทอรัลซึ่งแสดงถึง
\\ลักษณะ"\\\\"
แต่เนื่องจากเราต้องการreplacementถือแบ็กสแลชสองตัวเราจึงจำเป็นต้องใช้"\\\\\\\\"(แต่ละตัว\แสดงด้วยหนึ่ง"\\\\")
ดังนั้นเวอร์ชันที่มีreplaceAllลักษณะเช่นนี้
replaceAll("\\\\", "\\\\\\\\");
วิธีที่ง่ายกว่า
เพื่อให้ชีวิตง่ายขึ้น Java มีเครื่องมือในการหลีกเลี่ยงข้อความเข้าtargetและreplacementส่วนต่างๆโดยอัตโนมัติ ตอนนี้เราสามารถมุ่งเน้นเฉพาะสตริงและลืมเกี่ยวกับไวยากรณ์ regex:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
ซึ่งในกรณีของเราอาจมีลักษณะดังนี้
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
ดียิ่งขึ้น
หากเราไม่ต้องการการสนับสนุนไวยากรณ์ regex จริงๆอย่าให้เกี่ยวข้องreplaceAllเลย replaceแทนที่จะช่วยให้การใช้งาน ทั้งสองวิธีจะแทนที่s ทั้งหมด targetแต่replaceไม่เกี่ยวข้องกับไวยากรณ์ regex คุณก็เขียนได้
theString = theString.replace("\\", "\\\\");