2009-11-09 17 views
90

के साथ एकल बैकस्लैश मैं String\\something\\replaceAll का उपयोग करते हुए String\something\ कन्वर्ट करने के लिए कोशिश कर रहा हूँ, लेकिन मैं त्रुटियों के सभी प्रकार हो रहा है। मैंने सोचा था कि इस समाधान था:String.replaceAll डबल बैकस्लैश

theString.replaceAll("\\", "\\\\"); 

लेकिन यह नीचे अपवाद देता है:

java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 

उत्तर

162

String#replaceAll() तर्क को regular expression के रूप में व्याख्या करता है। \मेंString और regex दोनों में एक बच निकला चरित्र है। आप इसे regex के लिए दोबारा से बचने के लिए की जरूरत है:

string.replaceAll("\\\\", "\\\\\\\\"); 

लेकिन तुम जरूरी इस के लिए regex की जरूरत नहीं है, बस क्योंकि आप एक सटीक चरित्र-दर-चरित्र प्रतिस्थापन चाहते हैं और आप यहाँ पैटर्न जरूरत नहीं है। तो String#replace() पर्याप्त होना चाहिए:

string.replace("\\", "\\\\"); 

अद्यतन: टिप्पणियों के अनुसार, आप जावास्क्रिप्ट संदर्भ में स्ट्रिंग का उपयोग करना चाहते करने के लिए दिखाई देते हैं। अधिक वर्णों को कवर करने के लिए आप शायद StringEscapeUtils#escapeEcmaScript() का बेहतर उपयोग करेंगे।

+0

असल में, इसका उपयोग जावास्क्रिप्ट एएसटी में किया जाता है जिसे स्रोत में वापस परिवर्तित किया जाना चाहिए। आपका समाधान काम करता है। धन्यवाद! –

+0

यदि आप 'स्ट्रिंग # replaceAll()' का उपयोग करना चाहते हैं, तो आप [Matcher # quoteReplacement()] के साथ प्रतिस्थापन स्ट्रिंग को उद्धृत कर सकते हैं (http://docs.oracle.com/javase/7/docs/api/java/ उपयोग/regex/Matcher.html # उद्धरण प्रतिस्थापन (java.lang.String)): 'theString.replaceAll (" \\ ", Matcher.quoteReplacement (" \\\\ "));' –

6

आप पहली बहस में (भाग निकले) बैकस्लैश से बचने के लिए के रूप में यह एक रेगुलर एक्सप्रेशन है की आवश्यकता होगी। रिप्लेसमेंट (2 तर्क - Matcher#replaceAll(String) देखें) भी यह बैकस्लैश का विशेष अर्थ है है, तो आप के लिए उन प्रतिस्थापित करना होगा:

theString.replaceAll("\\\\", "\\\\\\\\"); 
3

हाँ ... समय से regex संकलक पैटर्न आपके द्वारा दिए गए देखता है यह, यह केवल एक बैकस्लैश देखता है (चूंकि जावा के लेक्सर ने डबल बैकवैक को एक ही में बदल दिया है)। "\\\\" के साथ "\\\\" को प्रतिस्थापित करने की आवश्यकता है, मान लीजिए या नहीं! जावा वास्तव में एक अच्छा कच्चे स्ट्रिंग वाक्यविन्यास की जरूरत है।

12

इस प्रकार की परेशानी से बचने के लिए, आप (जो एक नियमित अभिव्यक्ति लेता है) के बजाय replace (जो एक सादा स्ट्रिंग लेता है) का उपयोग कर सकते हैं। आपको अभी भी बैकस्लाश से बचने की आवश्यकता होगी, लेकिन नियमित अभिव्यक्तियों के साथ आवश्यक जंगली तरीकों में नहीं।

4

replaceAll(target, replacement)target के लिए नियमित अभिव्यक्ति (रेगेक्स) वाक्यविन्यास का उपयोग करता है और आंशिक रूप से replacement के लिए उपयोग करता है।

समस्या है कि \ regex में विशेष वर्ण है (जैसे \d अंकों का प्रतिनिधित्व करता है) और स्ट्रिंग में है शाब्दिक (जैसे \n दोहरे उद्धरण प्रतीक को प्रदर्शित करने लाइन विभाजक या \" बनाने के लिए), और \ प्रतीक बनाने के लिए हम इसे से बचने के लिए की जरूरत है इन दोनों स्तरों पर अतिरिक्त \ के साथ।

तो target regex जो \ प्रतीक हम इसे दो बार से बचने के लिए की जरूरत का प्रतिनिधित्व करेगा बनाने के लिए: रेगुलर एक्सप्रेशन \\

  • स्ट्रिंग में

    • शाब्दिक "\\\\" (प्रत्येक \ अपने स्वयं के अतिरिक्त \ से पहले की जरूरत है)।

    replacement\ के मामले में भी विशेष एक अन्य विशेष वर्ण जो $ है से बचने के लिए है। $x नोटेशन के माध्यम से, रेगेक्स द्वारा मिलान किए गए डेटा का हिस्सा प्रतिस्थापित किया जा सकता है और प्रतिस्थापन में पुन: उपयोग किया जा सकता है, जैसे replaceAll("(\d)", "$1$1") प्रत्येक अंक को डुप्लिकेट करेगा।

    तो फिर, replacement में एकल\ के लिए हम दो बैकस्लैश का प्रतिनिधित्व पाठ की जरूरत है:

    • \\
    • लेकिन स्ट्रिंग शाब्दिक "\\\\"

    तरह \\ नज़र का प्रतिनिधित्व लेकिन जब से हम चाहते हैं दोडालने के लिए प्रतिस्थापन मेंहमें "\\\\\\\\" की आवश्यकता है (दो "\\\\")।

    replaceAll("\\\\", "\\\\\\\\"); 
    

    बाहर बनाने के लिए जीवन को आसान जावा स्वचालित रूप से target और replacement भागों में पाठ से बचने के लिए उपकरण प्रदान करता है। तो अब हम केवल तार पर ध्यान केंद्रित कर सकते हैं और रेगुलर एक्सप्रेशन से वाक्य रचना के बारे में भूल:

    replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement)) 
    

    जो हमारे मामले में की तरह

    replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\")) 
    

    या और भी आसान है अगर हम का उपयोग नहीं करना चाहते हैं देख सकते हैं regex में replaceAll शामिल नहीं है और इसके बजाय replace का उपयोग करने दें (दोनों विधियां सभी target एस को प्रतिस्थापित करेंगी, लेकिन दूसरे में रीगेक्स वाक्यविन्यास शामिल नहीं है)। तो आप बस

    theString = theString.replace("\\", "\\\\") 
    
  • संबंधित मुद्दे