सभी विशेष वर्णों की सूची जिन्हें एक रेगेक्स में भाग जाने की आवश्यकता है


108

मैं एक ऐसा एप्लिकेशन बनाने की कोशिश कर रहा हूं जो एक संदेश के साथ एक संदेश टेम्पलेट से मेल खाता है जिसे एक उपयोगकर्ता भेजने की कोशिश कर रहा है। मैं संदेश के मिलान के लिए जावा रेगेक्स का उपयोग कर रहा हूं। टेम्पलेट / संदेश में विशेष वर्ण हो सकते हैं।

मुझे उन विशेष पात्रों की पूरी सूची कैसे मिलेगी जिन्हें मेरे regex को काम करने और अधिकतम संभावित मामलों में मिलान करने के लिए भाग जाने की आवश्यकता है?

जावा रेगेक्स में सभी विशेष पात्रों से बचने के लिए एक सार्वभौमिक समाधान है?

जवाबों:


94

आप पैटर्न वर्ग के javadoc को देख सकते हैं: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

यदि आप नियमित चार और विशेष अर्थ नहीं चाहते हैं तो आपको वहां सूचीबद्ध किसी भी चार से बचने की आवश्यकता है।

एक सरल उपाय के रूप में, आप टेम्पलेट को \ Q और \ E के बीच रख सकते हैं - उनके बीच का सब कुछ बच गया माना जाता है।


43
यदि आपको \ Q और \ E याद रखना मुश्किल है तो आप इसके बजाय पैटर्न का उपयोग कर सकते हैं ।quote ("...")
mkdev

19
काश, आप वास्तव में उन्हें कहते हैं
Dubinsky

क्यों, @AleksandrDubinsky?
सोरिन

55
@Sorin क्योंकि यह स्टैक एक्सचेंज की आत्मा (nay, पॉलिसी?) है, जो आपके उत्तर के उत्तर को केवल ऑफ-साइट संसाधन से जोड़ने के बजाय आपके उत्तर में बताती है। इसके अलावा, उस पृष्ठ की स्पष्ट सूची भी नहीं है। एक सूची यहां देखी जा सकती है: docs.oracle.com/javase/tutorial/essential/regex/literals.html , फिर भी यह बताती है कि "कुछ विशेष स्थितियों में ऊपर सूचीबद्ध विशेष वर्णों को मेटाचैटर्स के रूप में नहीं माना जाएगा," बिना यह जाने कि क्या होगा। अगर कोई उनसे बचने की कोशिश करता है। संक्षेप में, यह प्रश्न एक अच्छे उत्तर के योग्य है।
हांग्जो डबिन्स्की

8
"उनके बीच [ \Qऔर \E] सब कुछ बच गया माना जाता है" - अन्य के अलावा \Qऔर \E(जो मूल रूप से मूल रेक्स के भीतर हो सकता है) को छोड़कर । इसलिए, यहांPattern.quote सुझाए गए तरीके से उपयोग करना बेहतर है और पहिया को सुदृढ़ करना नहीं है।
साशा

92
  • जावा अक्षर जिन्हें नियमित अभिव्यक्तियों में बचना है:
    \.[]{}()<>*+-=!?^$|
  • समापन कोष्ठक के दो ( ]और }) केवल उसी प्रकार के ब्रैकेट को खोलने के बाद बच जाने की आवश्यकता है।
  • में []-brackets कुछ अक्षर (जैसे +और -) कभी कभी भागने के बिना काम करते हैं।

क्या बचने का कोई रास्ता नहीं है लेकिन उन पात्रों को अनुमति दें?
डोमिनिका

1
एक चरित्र से बचने का मतलब चरित्र को एक ऑपरेटर के रूप में व्याख्या करने के बजाय उसे अनुमति देना है।
तोबी जी

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

1
यद्यपि स्वीकृत उत्तर प्रश्न का उत्तर देता है, फिर भी यह उत्तर मेरे लिए अधिक उपयोगी था जब मैं सिर्फ एक त्वरित सूची की तलाश कर रहा था।
पुराना निक

-=!जरूरी नहीं कि वह बच जाए, यह संदर्भ पर निर्भर करता है। उदाहरण के लिए एक एकल पत्र के रूप में वे एक निरंतर रेगेक्स के रूप में काम करते हैं।
हॉक

29

बचने के लिए आप केवल जावा 1.5 से इसका उपयोग कर सकते हैं :

Pattern.quote("$test");

आप शब्द का सटीक मिलान करेंगे $test


यह सबसे उच्च श्रेणी का उत्तर क्यों नहीं है? यह उन सभी पात्रों को सूचीबद्ध करने के जटिल विवरण में जाने के बिना समस्या को हल करता है, जिन्हें भागने की जरूरत है और यह JDK का हिस्सा है - कोई अतिरिक्त कोड लिखने की आवश्यकता नहीं है! सरल!
वोक्समैन

17

के अनुसार स्ट्रिंग literals / अक्षरों से परे प्रलेखन पेज, वे हैं:

<([{\^-=$!|]})?*+.>

यह भी अच्छा होगा कि सूची कोड में कहीं न कहीं रेफरी हो, लेकिन मुझे नहीं पता कि यह कहां हो सकता है ...


11
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
मारबेल 18२

1
पैटर्न javadoc का कहना है कि किसी भी वर्णमाला वर्ण से पहले बैकस्लैश का उपयोग करना एक त्रुटि है जो एक बच गए निर्माण को निरूपित नहीं करता है, लेकिन एक बैकस्लैश का उपयोग गैर-वर्णनात्मक चरित्र से पहले किया जा सकता है, भले ही वह चरित्र एक गैर-निर्मित निर्माण का हिस्सा हो। इसलिए बहुत सरल रीगेक्स पर्याप्त होगा: s.replaceAll("[\\W]", "\\\\$0")जहां \Wगैर-शब्द वर्णों को नामित करता है।
जो बोबीबर

6

सभी ने जो कहा, उसे जोड़ते हुए, मैं निम्नलिखित का प्रस्ताव करता हूं, विशेष रूप से RegExp में विशेष रूप से सूचीबद्ध पात्रों की सूची को अपने स्वयं के स्ट्रिंग में सूचीबद्ध करने के लिए, और "\\" के हजारों नेत्रहीन रूप से पार्स करने की कोशिश से बचने के लिए। यह मेरे लिए बहुत अच्छा काम करता है:

final String regExSpecialChars = "<([{\\^-=$!|]})?*+.>";
final String regExSpecialCharsRE = regExSpecialChars.replaceAll( ".", "\\\\$0");
final Pattern reCharsREP = Pattern.compile( "[" + regExSpecialCharsRE + "]");

String quoteRegExSpecialChars( String s)
{
    Matcher m = reCharsREP.matcher( s);
    return m.replaceAll( "\\\\$0");
}

5

जावा पैटर्न डॉक्स के @ सोरिन के सुझाव पर, ऐसा लगता है कि बचने के लिए चार्ट कम से कम हैं:

\.[{(*+?^$|

4
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
fracz

2
)बचना भी पड़ता है, और इस बात पर निर्भर करता है कि आप किसी वर्ण वर्ग के अंदर या बाहर हैं, बचने के लिए और अधिक पात्र हो सकते हैं, इस स्थिति Pattern.quoteमें चरित्र वर्ग के अंदर और बाहर दोनों के उपयोग के लिए स्ट्रिंग से बचने में काफी अच्छा काम करता है।
न्हात्थ

3

Pattern.quote(String s)आप क्या चाहते हैं की तरह है। हालाँकि यह वांछित होने के लिए थोड़ा बचा है; यह वास्तव में व्यक्तिगत पात्रों से नहीं बचता है, बस स्ट्रिंग को लपेटता है \Q...\E

ऐसी कोई विधि नहीं है जो ठीक वही है जो आप खोज रहे हैं, लेकिन अच्छी खबर यह है कि वास्तव में जावा नियमित अभिव्यक्ति में सभी विशेष वर्णों से बचने के लिए यह काफी सरल है:

regex.replaceAll("[\\W]", "\\\\$0")

यह काम क्यों करता है? खैर, प्रलेखन के लिए Patternविशेष रूप से कहते हैं कि गैर-वर्णनात्मक वर्णों से बचने के लिए इसकी अनुमति है जो जरूरी नहीं कि बच जाना चाहिए:

किसी अक्षरात्मक चरित्र से पहले बैकस्लैश का उपयोग करना एक त्रुटि है जो एक बच गए निर्माण को निरूपित नहीं करता है; ये नियमित-अभिव्यक्ति भाषा के लिए भविष्य के एक्सटेंशन के लिए आरक्षित हैं। एक गैर-वर्णनात्मक चरित्र से पहले एक बैकस्लैश का उपयोग किया जा सकता है, भले ही वह चरित्र एक गैर-निर्मित निर्माण का हिस्सा हो।

उदाहरण के लिए, ;एक नियमित अभिव्यक्ति में एक विशेष चरित्र नहीं है। हालाँकि, यदि आप इसे छोड़ देते हैं, तब Patternभी व्याख्या \;करेंगे ;। यहाँ कुछ और उदाहरण दिए गए हैं:

  • >के \>बराबर हो जाता है>
  • [बन जाता है \[जो बच गया रूप है[
  • 8अभी भी है 8
  • \)वह बन जाता है, \\\)जिसका संक्षिप्त रूप \और (संक्षिप्त रूप होता है।

नोट: कुंजी "गैर-अल्फाबेटिक" की परिभाषा है, जिसका दस्तावेज़ीकरण वास्तव में "गैर- शब्द " वर्ण या वर्ण सेट के बाहर वर्ण का अर्थ है [a-zA-Z_0-9]


2

सिक्के के दूसरी तरफ, आपको "गैर-चार" रेगेक्स का उपयोग करना चाहिए जो इस तरह दिखता है यदि आपके वर्ण संदर्भ में विशेष वर्ण = ऑलकार्स - संख्या - एबीसी - स्थान।

String regepx = "[^\\s\\w]*";

2

हालाँकि इसका उत्तर जावा के लिए है, लेकिन कोड को आसानी से इस कोटलिन स्ट्रिंग एक्सटेंशन से अनुकूलित किया जा सकता है, जो कि (@brcolow द्वारा प्रदान किया गया) से अनुकूलित किया गया है:

private val escapeChars = charArrayOf(
    '<',
    '(',
    '[',
    '{',
    '\\',
    '^',
    '-',
    '=',
    '$',
    '!',
    '|',
    ']',
    '}',
    ')',
    '?',
    '*',
    '+',
    '.',
    '>'
)

fun String.escapePattern(): String {
    return this.fold("") {
      acc, chr ->
        acc + if (escapeChars.contains(chr)) "\\$chr" else "$chr"
    }
}

fun main() {
    println("(.*)".escapePattern())
}

प्रिंट \(\.\*\)

इसे क्रिया में यहाँ देखें https://pl.kotl.in/h-3mXZkNE


1

यह मानते हुए कि आपके पास और विश्वास है (आधिकारिक होने के लिए) भागने के पात्रों की सूची जावा रेगेक्स का उपयोग करता है (अच्छा होगा यदि ये चरित्र कुछ पैटर्न वर्ग के सदस्य में उजागर हुए थे) आप चरित्र से बचने के लिए निम्न विधि का उपयोग कर सकते हैं यदि यह वास्तव में आवश्यक है:

private static final char[] escapeChars = { '<', '(', '[', '{', '\\', '^', '-', '=', '$', '!', '|', ']', '}', ')', '?', '*', '+', '.', '>' };

private static String regexEscape(char character) {
    for (char escapeChar : escapeChars) {
        if (character == escapeChar) {
            return "\\" + character;
        }
    }
    return String.valueOf(character);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.