2012-05-19 21 views
17

क्या कोई विशेष वर्ण (मेटा-कैरेक्टर) से बचने के लिए जावा या किसी ओपन सोर्स लाइब्रेरी में नियमित अभिव्यक्ति के रूप में उपयोग करने के लिए कोई विधि है?जावा नियमित अभिव्यक्तियों में विशेष वर्णों से बचने

यह प्रत्येक व्यक्तिगत चरित्र को मैन्युअल रूप से बचने के बिना गतिशील रूप से नियमित अभिव्यक्ति बनाने में बहुत आसान होगा।

उदाहरण के लिए, पर विचार \d+\.\d+ की तरह एक साधारण regex कि 1.2 की तरह एक दशमलव बिंदु के साथ नंबर से मेल खाता है, साथ ही निम्न कोड:

String digit = "d"; 
String point = "."; 
String regex1 = "\\d+\\.\\d+"; 
String regex2 = Pattern.quote(digit + "+" + point + digit + "+"); 

Pattern numbers1 = Pattern.compile(regex1); 
Pattern numbers2 = Pattern.compile(regex2); 

System.out.println("Regex 1: " + regex1); 

if (numbers1.matcher("1.2").matches()) { 
    System.out.println("\tMatch"); 
} else { 
    System.out.println("\tNo match"); 
} 

System.out.println("Regex 2: " + regex2); 

if (numbers2.matcher("1.2").matches()) { 
    System.out.println("\tMatch"); 
} else { 
    System.out.println("\tNo match"); 
} 

नहीं आश्चर्यजनक रूप से, उत्पादन ऊपर कोड से तैयार की है:

Regex 1: \d+\.\d+ 
    Match 
Regex 2: \Qd+.d+\E 
    No match 

है, regex1 मैचों 1.2 लेकिन regex2 (जो "गतिशील" का निर्माण किया है) नहीं (इसके बजाय, यह शाब्दिक स्ट्रिंग से मेल खाता है +०१२३७७६२१२)।

तो, क्या कोई ऐसी विधि है जो स्वचालित रूप से प्रत्येक रेगेक्स मेटा-कैरेक्टर से बच जाएगी?

अगर वहाँ थे,, मान लें कि java.util.regex.Pattern में एक स्थिर escape() विधि,

Pattern.escape('.') 

के उत्पादन में स्ट्रिंग "\." होगा, लेकिन

Pattern.escape(',') 

सिर्फ "," प्रस्तुत करना चाहिए, क्योंकि यह है एक मेटा-चरित्र नहीं। इसी तरह,

Pattern.escape('d') 

"\d" उत्पादन कर सकता है, 'd' के बाद अंक निरूपित करने के लिए (हालांकि एस्केपिंग इस मामले में कोई मतलब नहीं हो सकता है प्रयोग किया जाता है, के रूप में 'd' अर्थ हो सकता है शाब्दिक 'd', जो regex interpeter द्वारा गलत समझा नहीं जाएगा, वे करने के लिए कुछ और, जैसा कि '.' के साथ होगा)।

+0

है कैसे इस तरह के एक विधि beween एक 'मतलब d' अंतर निर्धारित करेंगे मिलान करने के लिए पाठ में मेटा चरित्र और 'd' के रूप में? ('उद्धरण (" डी + डॉलर? ")' '\\ d + \\ डॉलर \\ s?" 'एक छोटी उद्धरण विधि में होगा।) – rsp

+0

सही, यही कारण है कि मैं एक विधि के लिए पूछ रहा हूं जो बच जाएगा व्यक्तिगत पात्र! :-) – PNS

+0

केवल व्यक्तिगत वर्णों से बचने के लिए आप एक शब्द सीमा से मेल खाने के साथ खेल सकते हैं, जैसे कुछ: 's/\ b ([dswDSW]) \ b/\\ $ 1/g;' – rsp

उत्तर

19

मुझे 100% यकीन नहीं है कि यह वही है जो आप यहां पूछ रहे हैं। आप देख रहे हैं स्थिरांक है कि आप अपने regex पैटर्न में तो उपयोग कर सकते हैं बस के साथ "\\" उन्हें prepending बनाने का एक तरीका के लिए काम करेगा:

String digit = "\\d"; 

कोई Pattern विधि है कि मुझे लगता है कि के बारे में पता करने के लिए ऐसा करता है आप। दुर्भाग्यवश, हालांकि "\\d" अंक के लिए "\\w" कार्य वर्णों के लिए, () समूह, + और * दोहराने के लिए भी है, लेकिन नियमित अभिव्यक्ति के प्रत्येक भाग से निपटने का एक आम तरीका नहीं है।

अपनी पोस्ट में आप Pattern.quote(string) method का उपयोग करते हैं।आप शायद जानते हैं कि इस "\\Q" और "\\E" के बीच अपने पैटर्न लपेटता है ताकि आप एक स्ट्रिंग मिलान कर सकते हैं, भले ही यह आप के रूप में ग्रे के साथ सहमत यह (+, ., \\d, आदि)

+1

मुझे उद्धरण() के बारे में पता है और यदि आप ऊपर नमूना आउटपुट देखते हैं तो इसमें \ Q और \ E शामिल हैं। दरअसल, मैं सिर्फ जावा रेगेक्स के लिए एक चरित्र के बच निकले संस्करण का उत्पादन करने के लिए एक विधि की तलाश कर रहा था। इसलिए, उदाहरण के लिए, बच निकला कॉमा एक अल्पविराम रहेगा, लेकिन बच निकला अवधि \ और इसी तरह। – PNS

5

रेगेक्स मैचर जानता है कि आप एक अंक की तलाश कर रहे हैं और पत्र d पत्र से बचने के लिए पत्र नहीं है (\d)। जावा में रेगेक्स एस्केप कैरेक्टर टाइप करने के लिए, आपको इसे से बचने की जरूरत है (इसलिए \\\ बन जाता है)। तो, विशेष रेगेक्स वर्णों के लिए डबल बैकस्लाश टाइप करने के आसपास कोई रास्ता नहीं है।

+0

बिल्कुल, इसलिए मुझे एक ऐसी विधि चाहिए जो एक चरित्र को रेगेक्स (यानी, शाब्दिक नहीं) स्ट्रिंग में से बचें। – PNS

+0

आप अपनी खुद की 'एस्केप()' विधि लिख सकते हैं जो 'पैरामीटर – Attila

+1

पर टर्मिनोलॉजी के बारे में स्पष्ट होने के लिए, गैर-विशेष चरित्र को बैकस्लैश जोड़ने से बचने के लिए नहीं कहा जाता है। लिखने के लिए '\ d' किसी भी तरह से "पत्र से बचें" 'd' नहीं है। इसके बजाय यह एक पूरी तरह से विशिष्ट अवधारणा बनाता है, एक वर्ण वर्ग जो अंकों का प्रतिनिधित्व करता है। बचने का एक उदाहरण आपका दूसरा मामला होगा, स्लैश चरित्र का प्रतिनिधित्व करने के लिए '\\' लिखना। – AndrewF

1

में एक विशेष regex चरित्र है, क्या होता है लिटरल (\ [, \]) और मेटा-वर्ण ([,]) दोनों के लिए आपके पैटर्न की आवश्यकता हो सकती है। तो कुछ उपयोगिता के साथ आप पहले सभी पात्रों से बचने में सक्षम होना चाहिए और फिर आप मेटा-वर्ण जोड़ सकते हैं जिसे आप एक ही पैटर्न पर जोड़ना चाहते हैं।

Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\\[\\].+*?^$\\\\|]"); 

और इस पद्धति में इसका इस्तेमाल करते हैं:

String escapeSpecialRegexChars(String str) { 

    return SPECIAL_REGEX_CHARS.matcher(str).replaceAll("\\\\$0"); 
} 

तो फिर तुम उदाहरण के लिए इस तरह उपयोग कर सकते हैं,:

Pattern toSafePattern(String text) 
{ 
    return Pattern.compile(".*" + escapeSpecialRegexChars(text) + ".*"); 
} 

हम जरूरत

19

मैं इस पैटर्न में लिखा था ऐसा करने के लिए, क्योंकि भागने के बाद, हम कुछ regex अभिव्यक्ति जोड़ते हैं। यदि नहीं, तो आप बस \Q और \E उपयोग कर सकते हैं:

Pattern toSafePattern(String text) 
{ 
    return Pattern.compile(".*\\Q" + text + "\\E.*") 
} 
+3

यह मेरे लिए काम नहीं करता (कम से कम स्कैला में), लेकिन यह एक किया: '" [\\ {\\} \\ (\\) \\ [\\] \\। \\ + \\ * \\? \\^\\ $ \\\\\\ |] "' – redent84

+0

यहां विशेष वर्णों की एक पूरी सूची है: http://stackoverflow.com/a/27454382/1490986 –

0

उपयोग

pattern.compile("\""); 
String s= p.toString()+"yourcontent"+p.toString(); 

yourcontent के रूप में परिणाम दे देंगे के रूप में

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