2012-02-02 20 views
10

में बैकस्लैश से बचने के लिए संदर्भ के साथ की जरूरत है प्रश्न के नीचे - String.replaceAll single backslashes with double backslashesजावा, नियमित अभिव्यक्ति, करने के लिए regex

मैं एक परीक्षण कार्यक्रम को लिखा था और मैंने पाया कि परिणाम दोनों ही मामलों में सच है, कि क्या मैं बैकस्लैश से बचने या नहीं। ऐसा इसलिए हो सकता है क्योंकि - \ t एक मान्यता प्राप्त जावा स्ट्रिंग एस्केप अनुक्रम है। (कोशिश करें और यह शिकायत करेगा)। - \ t को रेगेक्स में शाब्दिक टैब के रूप में लिया जाता है। मैं कुछ कारणों से अनिश्चित हूं।

क्या जावा में रेगेक्स से बचने के बारे में कोई सामान्य दिशानिर्देश है। मुझे लगता है कि दो बैकस्लाश का उपयोग सही दृष्टिकोण है।

मैं अभी भी आपकी राय जानना चाहता हूं।

public class TestDeleteMe { 

    public static void main(String args[]) { 
    System.out.println(System.currentTimeMillis()); 

    String str1 = "a b"; //tab between a and b 

    //pattern - a and b with any number of spaces or tabs between 
    System.out.println("matches = " + str1.matches("^a[ \\t]*b$")); 
    System.out.println("matches = " + str1.matches("^a[ \t]*b$")); 
    } 
} 

उत्तर

6

प्रथम रूप \\t पैटर्न वर्ग द्वारा एक टैब वर्ण के लिए विस्तार किया जाएगा।

दूसरे फॉर्म \t को पैटर्न बनाने से पहले जावा द्वारा टैब टैब में विस्तारित किया जाएगा।

अंत में, आपको एक टैब चार या तो रास्ता मिलता है।

+5

यह सही है, * "मुझे विश्वास है" * आवश्यक नहीं है। जावा स्ट्रिंग में '" \\ टी "' '\ t "' में अनुवाद करता है, जो रेगेक्स इंजन में एक टैब कैरेक्टर में अनुवाद करता है। '" \ T "' जावा स्ट्रिंग में एक टैब वर्ण में अनुवाद करता है, जो रेगेक्स में अपरिवर्तित बनी हुई है। – Tomalak

+0

धन्यवाद। मै समझता हुँ। – RuntimeException

+0

@Tomalak _'I believe'_ bit से छुटकारा पा लिया ... इसके बारे में खेद है ... –

9

भागने के अनुक्रमों की दो व्याख्याएं चल रही हैं: पहले जावा कंपाइलर द्वारा और फिर regexp इंजन द्वारा। जब जावा कंपाइलर दो स्लेश देखता है, तो यह उन्हें एक स्लैश से बदल देता है। जब स्लैश के बाद t होता है, तो जावा इसे एक टैब से बदल देता है; जब डबल-स्लैश के बाद t होता है, तो जावा इसे अकेला छोड़ देता है। हालांकि, क्योंकि दो स्लेशों को एक स्लैश द्वारा प्रतिस्थापित किया गया है, regexp इंजन \t देखता है, और इसे एक टैब के रूप में व्याख्या करता है।

मुझे लगता है कि यह regexp टैब के रूप में व्याख्या \t जाने के लिए (यानी लिखना जावा में "\\t") क्योंकि यह आपको डीबगिंग, प्रवेश, आदि के दौरान अपने उद्देश्य के रूप में अभिव्यक्ति को देखने आप Pattern\t साथ परिवर्तित तो देता है क्लीनर है स्ट्रिंग करने के लिए, आपको अपनी नियमित अभिव्यक्ति के बीच में एक टैब वर्ण दिखाई देगा, और इसे अन्य व्हाइटस्पेस के लिए भ्रमित कर सकता है। \\t के साथ पैटर्न में यह समस्या नहीं है: वे आपको एक स्लैश के साथ \t दिखाएंगे, जो आपको बताएंगे कि वे किस प्रकार के व्हाइटस्पेस से मेल खाते हैं।

+1

धन्यवाद। अब मैं समझता हूं कि रेगेक्स इंजन '[\ t]' (अंतरिक्ष के बाद \ t) और '[]' (अंतरिक्ष के बाद टैब) दोनों को समझता है और उन्हें समान करता है। क्या आपको लगता है कि मैं यह कहने में सही हूं? '[\ t]' हालांकि अधिक समझ में आता है। इसलिए मुझे जावा में '[\\ t] 'का उपयोग करना होगा। – RuntimeException

+0

@ सतीशमोत्वानी "जरूरी" एक शब्द बहुत मजबूत है, लेकिन regexp पर '\\ t' प्रवाह देना एक अच्छा अभ्यास है। – dasblinkenlight

6

हां, भागने के बारे में एक सामान्य दिशानिर्देश है: आपके जावा स्रोत में एस्केप अनुक्रम जावा कंपाइलर (या अंततः कुछ प्रीप्रोसेसर) द्वारा प्रतिस्थापित किया जाता है। संकलक किसी भी बचने के अनुक्रमों के बारे में शिकायत करेगा जो यह नहीं जानता है, उदा। \s। जब आप एक RegEx पैटर्न के लिए स्ट्रिंग अक्षर लिखते हैं, तो संकलक सामान्य रूप से इस शाब्दिक को संसाधित करेगा और सभी वर्णित अनुक्रमों को अनुसार वर्ण के साथ प्रतिस्थापित करेगा। फिर, जब प्रोग्राम निष्पादित किया जाता है, तो पैटर्न वर्ग इनपुट स्ट्रिंग को संकलित करता है, यानी, यह किसी अन्य समय से बचने के दृश्यों का मूल्यांकन करेगा। पैटर्न वर्ग \s को एक चरित्र वर्ग के रूप में जानता है और इसलिए इस वर्ग वाले पैटर्न को संकलित करने में सक्षम होगा। हालांकि, आपको जावा कंपाइलर से \s से बचने की आवश्यकता है जो इस भागने अनुक्रम को नहीं जानता है। ऐसा करने के लिए, आप बैकस्लैश से बचते हैं जिसके परिणामस्वरूप \\s होता है।

संक्षेप में, आपको हमेशा RegEx पैटर्न के लिए चरित्र कक्षाओं से बचने की आवश्यकता होती है। यदि आप बैकस्लैश से मेल खाना चाहते हैं, तो सही पैटर्न \\\\ है क्योंकि जावा कंपाइलर इसे \\ बना देगा जो पैटर्न कंपाइलर बच निकले बैकस्लैश चरित्र के रूप में पहचाना जाएगा।

+0

धन्यवाद। मै समझता हुँ। तो आपको जावा में अपना 'स्ट्रिंग' लिखना होगा ताकि पैटर्न इंजन को वह उम्मीद हो जो वह अपेक्षा करता है। मुझे लगता है कि भविष्य में जावा में रेगेक्स लिखते समय मुझे बहुत सावधान रहना होगा। – RuntimeException

0

org.apache.commons.lang3.StringEscapeUtils.unescapeJava (...) के साथ, आप अधिकांश सामान्य विभाजन से बच सकते हैं।वर्ण और यूनिकोड वर्ण भी (यूनिकोड वर्णमाला को पठनीय नियमित चरित्र में परिवर्तित करता है)

संबंधित मुद्दे