नियमित अभिव्यक्तियों में कौन से विशेष पात्रों को बचाना चाहिए?


389

मैं हमेशा अनुमान लगाने की कोशिश कर के थक गया हूं, अगर मुझे ()[]{}|रीजेक्स के कई कार्यान्वयन का उपयोग करते समय विशेष पात्रों जैसे ' ' आदि से बचना चाहिए ।

यह अलग है, उदाहरण के लिए, पायथन, sed, grep, awk, पर्ल, नाम, अपाचे, खोजें और इतने पर। क्या कोई नियम निर्धारित है जो बताता है कि मुझे कब होना चाहिए, और कब नहीं करना चाहिए, विशेष वर्णों से बचना चाहिए? क्या यह पीसीआरई, पॉसिक्स या विस्तारित रीजैक्स जैसे रीजेक्सपी प्रकार पर निर्भर करता है?


4
escape()रेगेक्स के पुर्जों के रूप में मनमाने ढंग से तारों का उपयोग करने की अनुमति देने के लिए अच्छे रेगेक्स पुस्तकालयों में " " जैसे कार्य हैं ।
ivan_pozdeev

2
आप ऑनलाइन रेगेक्स एक्सप्रेशन चेकर्स जैसे gskinner.com/RegExr (यह मुफ़्त है) का उपयोग कर सकते हैं । (में टाइप करें, फिर आपके द्वारा टाइप किए गए रेगेक्स पर माउस को हॉवर करें)
हेक्सिकल जूल

2
सभी गैर-अल्फ़ान्यूमेरिक वर्णों से बच जाएं। अवधि।
सलमान वॉन अब्बास

2
यह प्रश्न "अन्य" के तहत स्टैक ओवरफ्लो रेगुलर एक्सप्रेशन एफएक्यू में जोड़ा गया है ।
aliteralmind

1
इस सवाल को "एस्केप सीक्वेंस" के तहत स्टैक ओवरफ्लो रेगुलर एक्सप्रेशन एफएक्यू में जोड़ा गया है ।
aliteralmind

जवाबों:


365

आपको कौन से पात्र चाहिए और कौन से नहीं बचने चाहिए यह वास्तव में आपके द्वारा काम कर रहे रेगेक्स स्वाद पर निर्भर करता है।

पीसीआरई के लिए, और अधिकांश अन्य तथाकथित पर्ल-संगत जायके, इन बाहरी चरित्र वर्गों से बचें:

.^$*+?()[{\|

और ये चरित्र वर्ग के अंदर हैं:

^-]\

POSIX विस्तारित रेग्जेस (ERE) के लिए, इन बाहरी वर्ण वर्गों से बाहर निकलें (PCRE के समान)

.^$*+?()[{\|

किसी अन्य वर्ण से बचना POSIX ERE के साथ एक त्रुटि है।

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

[]^-]

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

.^$*[\

बीआरई में कोष्ठक और घुंघराले कोष्ठक से बचना उन्हें विशेष अर्थ देता है कि उनके बिना पढ़े हुए संस्करण ईआरई में हैं। कुछ कार्यान्वयन (जैसे GNU) बच जाने पर अन्य वर्णों को भी विशेष अर्थ देते हैं, जैसे कि \ _? और +। के अलावा अन्य वर्ण से बचना। ^ $ * () {} आम तौर पर BREs के साथ एक त्रुटि है।

चरित्र वर्ग के अंदर, BREE ERE के समान नियम का पालन करते हैं।

यदि यह सब आपके सिर को घुमाता है , तो RegexBuddy की एक प्रति पकड़ो । टैब बनाएँ पर, सम्मिलित करें पर क्लिक करें, और फिर लिटरल पर। RegexBuddy आवश्यकतानुसार बच निकलेगा।


1
ऐसा लगता है कि आप "/" को भूल गए, जिसे एक वर्ग के बाहर भागने की भी जरूरत है।
जैकटिपस्टर

11
/मेरे द्वारा उल्लिखित किसी भी नियमित अभिव्यक्ति के फ्लेवर में एक मेटाचैकर नहीं है, इसलिए नियमित अभिव्यक्ति सिंटैक्स को इससे बचने की आवश्यकता नहीं है। एक रेगुलर एक्सप्रेशन एक प्रोग्रामिंग भाषा में एक शाब्दिक, तो उस भाषा का स्ट्रिंग या रेगुलर एक्सप्रेशन से स्वरूपण नियमों की आवश्यकता हो सकती उद्धृत किया गया है जब /या "या 'भाग निकले हो सकता है, और यहां तक कि आवश्यकता हो सकती है `\` दोगुना भाग निकले किया जाना है।
जनवरी गोयवर्ट्स

2
बृहदान्त्र के बारे में क्या, ":"? क्या यह चरित्र वर्गों के साथ-साथ बाहर भी बच जाएगा? en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions का कहना है "PCRE में लगातार भागने के नियम हैं: किसी भी गैर-अल्फा-संख्यात्मक चरित्र का मतलब इसके शाब्दिक मूल्य से बच सकता है [...]
nicolallias

4
MAY बच जाए ऐसा नहीं है जैसे SHOULD बच जाए। PCRE सिंटैक्स को कभी भी शाब्दिक बृहदान्त्र से बचने की आवश्यकता नहीं होती है, इसलिए शाब्दिक कॉलोनों से बचना आपके regex को पढ़ने में कठिन बनाता है।
जन गोयवर्ट्स

1
गैर-पॉस ईआरई के लिए (एक जिसे मैं सबसे अधिक बार उपयोग करता हूं क्योंकि यह टीईसी द्वारा लागू किया गया है) अन्य चीजों से बचकर त्रुटियों को उत्पन्न नहीं करता है।
स्लीपबेटमैन

61

आधुनिक RegEx जायके (PCRE)

सी, सी ++, डेल्फी, एडिटपैड, जावा, जावास्क्रिप्ट, पर्ल, पीएचपी (PHP), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Real Studio, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML स्कीमा, Xojo, शामिल हैं। XRegExp।
PCRE संगतता भिन्न हो सकती है

    कहीं भी: . ^ $ * + - ? ( ) [ ] { } \ |


लीगेसी RegEx फ्लेवर (BRE / ERE)

Awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed शामिल हैं।
PCRE समर्थन बाद के संस्करणों में या एक्सटेंशन का उपयोग करके सक्षम किया जा सकता है

ERE / awk / egrep / Emacs

    एक चरित्र वर्ग के बाहर: एक चरित्र वर्ग के . ^ $ * + ? ( ) [ { } \ |
    अंदर:^ - [ ]

BRE / एड / ग्रेप / SED

    एक चरित्र वर्ग के बाहर: एक चरित्र वर्ग के . ^ $ * [ \
    अंदर: ^ - [ ]
    शाब्दिक के लिए, बच नहीं: + ? ( ) { } |
    मानक रीगेक्स व्यवहार के लिए, बच:\+ \? \( \) \{ \} \|


टिप्पणियाँ

  • यदि एक विशिष्ट चरित्र के बारे में अनिश्चित है, तो इसे जैसे बचा जा सकता है \xFF
  • अल्फ़ान्यूमेरिक वर्ण बैकस्लैश से बच नहीं सकते
  • मनमाने ढंग से प्रतीकों को PCRE में बैकस्लैश के साथ बचाया जा सकता है, लेकिन BRE / ERE नहीं (आवश्यकता पड़ने पर ही उन्हें बचना चाहिए)। पीसीआरई के लिए ] -केवल एक चरित्र वर्ग के भीतर भागने की जरूरत है, लेकिन मैंने उन्हें सादगी के लिए एक सूची में रखा
  • कोटेड एक्सप्रेशन स्ट्रिंग्स में आस-पास के भाव वर्ण भी होने चाहिए, और अक्सर बैकस्लैश डबल-अप (जैसे "(\")(/)(\\.)"एंगल /(")(\/)(\.)/से)
  • भागने के अलावा, विभिन्न रेगेक्स कार्यान्वयन अलग-अलग संशोधक, चरित्र वर्ग, एंकर, क्वांटिफायर और अन्य सुविधाओं का समर्थन कर सकते हैं। अधिक जानकारी के लिए, अपने एक्सप्रेशन को लाइव दिखाने के लिए regular-expressions.info देखें , या regex101.com का उपयोग करें

1
आपके उत्तर में कई त्रुटियां हैं, जिनमें शामिल हैं, लेकिन यह सीमित नहीं है: आपके "आधुनिक" जायकों में से -किसी ]को भी चरित्र वर्गों के बाहर भागने की आवश्यकता नहीं है । POSIX (BRE / ERE) में वर्ण वर्गों के अंदर भागने का चरित्र नहीं है। डेल्फी के आरटीएल में रेगेक्स का स्वाद वास्तव में पीसीआरई पर आधारित है। पायथन, रूबी और एक्सएमएल के अपने फ्लेवर होते हैं जो पीसीआर के करीब होते हैं और पॉसिक्स फ्लेवर की तुलना में।
जनवरी गोयवर्ट्स

1
@JanGoyvaerts सुधार के लिए धन्यवाद। आपके द्वारा बताए गए फ्लेवर वास्तव में पीसीआरई के करीब हैं। पलायन के लिए, मैंने उन्हें सादगी के लिए रखा; कुछ अपवादों की तुलना में हर जगह भागने के लिए याद रखना आसान है। पावर उपयोगकर्ताओं को पता होगा कि क्या हो रहा है, अगर वे कुछ बैकस्लैश से बचना चाहते हैं। वैसे भी, मैंने अपने उत्तर को कुछ स्पष्टीकरणों के साथ अपडेट किया है जो उम्मीद है कि इस सामान में से कुछ को संबोधित करेंगे।
बीजोर

22

दुर्भाग्य से वास्तव में भागने के कोड का एक सेट नहीं है क्योंकि यह उस भाषा के आधार पर भिन्न होता है जिसे आप उपयोग कर रहे हैं।

हालाँकि, रेग्युलर एक्सप्रेशन टूल्स पेज या इस रेगुलर एक्सप्रेशन चेटशीट जैसे पेज को रखने से आपको चीजों को जल्दी से फ़िल्टर करने में मदद मिल सकती है।


1
वेटबाइट्स की धोखा देने वाली शीट मोटे तौर पर ओवरसाइम्प्लीफाइड होती है, और इसमें कुछ चमकती त्रुटियां होती हैं। उदाहरण के लिए, यह कहता है \<और \>शब्द सीमाएं हैं, जो कि बूस्ट रेगेक्स लाइब्रेरी में केवल (एएफएआईके) सच है। लेकिन कहीं यह कहता है <और >अक्षरों से परे हैं और (भाग जाना चाहिए \<और \>) उन्हें सचमुच, किसी भी स्वाद में जो सच नहीं मैच के लिए
एलन मूर

5

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

तो आपको वास्तव में यह जानना होगा कि आप किस शैली को उद्धृत करने की कोशिश कर रहे हैं।


5

POSIX नियमित अभिव्यक्ति पर कई भिन्नताओं को पहचानता है - मूल नियमित अभिव्यक्ति (BRE) और विस्तारित नियमित अभिव्यक्ति (ERE)। और फिर भी, POSIX द्वारा मानकीकृत उपयोगिताओं के ऐतिहासिक कार्यान्वयन के कारण quirks हैं।

कब कौन सा नोटेशन प्रयोग करना है या कौन सा नोटेशन कमांड प्रयोग करता है इसके लिए कोई सरल नियम नहीं है।

जेफ फ्रीडल की मास्टेरिंग रेगुलर एक्सप्रेशंस बुक देखें।


4

वास्तव में, वहाँ नहीं है। लगभग आधे-बिलियन भिन्न रेगेक्स सिंटैक्स होते हैं; वे सामान्य रूप से पर्ल, ईएमएसीएस / जीएनयू और एटीएंडटी में आते हैं, लेकिन मुझे हमेशा आश्चर्य हो रहा है।


4

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

sed -e 's/foo\(bar/something_else/'

मैं इसके बजाय केवल एक साधारण चरित्र वर्ग परिभाषा का उपयोग करता हूं, इसलिए उपरोक्त अभिव्यक्ति बन जाती है

sed -e 's/foo[(]bar/something_else/'

जो मुझे सबसे अधिक regexp कार्यान्वयन के लिए काम करता है।

BTW चरित्र वर्ग बहुत वेनिला regexp घटक हैं, इसलिए वे ज्यादातर स्थितियों में काम करते हैं जहां आपको rexxps में पात्रों से बचने की आवश्यकता होती है।

संपादित करें: नीचे दी गई टिप्पणी के बाद, मैंने सोचा कि मैं इस तथ्य का उल्लेख करूंगा कि आपको regexp मूल्यांकन के व्यवहार को देखते हुए परिमित राज्य ऑटोमेटा और गैर-परिमित राज्य ऑटोमेटा के बीच के अंतर पर भी विचार करना होगा।

आप "चमकदार बॉल बुक" उर्फ ​​इफेक्टिव पर्ल ( सैनिटाइज्ड अमेजन लिंक ) को देखना पसंद कर सकते हैं , विशेष रूप से रेग्युलर एक्सप्रेशंस के चैप्टर को, इसके लिए regexp इंजन मूल्यांकन प्रकारों में अंतर महसूस कर सकते हैं।

दुनिया के सभी एक पीसीआरई नहीं!

वैसे भी, SNgeOL की तुलना में regexp बहुत क्लूनी हैं ! अब वह एक दिलचस्प प्रोग्रामिंग कोर्स था! साथ में सिमुला पर ।

आह 70 के दशक के अंत में UNSW में अध्ययन की खुशियाँ! (-:


'sed' एक कमांड है जिसके लिए प्लेन '(' विशेष नहीं है, लेकिन '\' (विशेष है;), इसके विपरीत, PCRE इस अर्थ को उलट देता है, इसलिए '(' विशेष है, लेकिन '\' (नहीं है।) बिल्कुल यही है। ओपी के बारे में पूछ रहा है।
जोनाथन लेफ़लर

sed एक * nix उपयोगिता है जो regexp मूल्यांकन के सबसे आदिम सेटों में से एक का उपयोग करता है। पीसीआरई उस स्थिति में प्रवेश नहीं करता है जिसका मैं वर्णन करता हूं कि इसमें एक अलग वर्ग (इन) परिमित ऑटोमेटा शामिल है जिस तरह से यह रीजैक्स का मूल्यांकन करता है। मुझे लगता है कि regexp सिंटैक्स के न्यूनतम सेट के लिए मेरा सुझाव अभी भी है।
रोब वेल्स

1
POSIX- अनुरूप प्रणाली पर, POSIX BRE का उपयोग करता है, जिसे मैं अपने उत्तर में कवर करता हूं। आधुनिक लिनक्स सिस्टम पर GNU संस्करण कुछ एक्सटेंशन के साथ POSIX BRE का उपयोग करता है।
जन गोयवर्ट्स

2

PHP के लिए, "यह निर्दिष्ट करने के लिए हमेशा गैर-अल्फ़ान्यूमेरिक" \ "से पहले सुरक्षित है कि यह अपने लिए खड़ा हो।" - http://php.net/manual/en/regexp.reference.escape.php

सिवाय अगर यह एक "या 'है।: /

PHP में regex पैटर्न चर (या आंशिक चर) से बचने के लिए preg_quote () का उपयोग करें


2

यह जानने के लिए कि कब और क्या बिना प्रयास के बचना जरूरी है, यह समझने के लिए कि किन संदर्भों की श्रृंखला स्ट्रिंग से होकर गुजरती है। आप सबसे दूर की ओर से स्ट्रिंग को उसके अंतिम गंतव्य तक निर्दिष्ट करेंगे जो कि रेगेक्सपी पार्सिंग कोड द्वारा नियंत्रित की गई मेमोरी है।

याद रखें कि मेमोरी में स्ट्रिंग कैसे संसाधित होती है: यदि कोड के अंदर एक सादा स्ट्रिंग हो सकता है, या कमांड लाइन में एक स्ट्रिंग दर्ज की जा सकती है, लेकिन हो सकता है या तो एक इंटरेक्टिव कमांड लाइन हो या शेल स्क्रिप्ट फ़ाइल के अंदर बताई गई कमांड लाइन, या कोड के द्वारा उल्लिखित मेमोरी में एक चर के अंदर, या आगे के मूल्यांकन के माध्यम से (स्ट्रिंग) तर्क, या एक स्ट्रिंग जिसमें कोड गतिशील रूप से किसी भी प्रकार के एनकैप्सुलेशन के साथ उत्पन्न होता है ...

इस संदर्भ में से प्रत्येक ने कुछ पात्रों को विशेष कार्यक्षमता के साथ सौंपा।

जब आप अक्षर को उसके विशेष कार्य (संदर्भ के लिए स्थानीय) का उपयोग किए बिना शाब्दिक रूप से पारित करना चाहते हैं, तो इससे आपको अगले संदर्भ के लिए इसे बचाना होगा, जिसके लिए कुछ अन्य भागने वाले पात्रों की आवश्यकता हो सकती है, जो इसके अतिरिक्त होने की आवश्यकता हो सकती है पूर्ववर्ती सन्दर्भ में बच गए। इसके अलावा चरित्र एन्कोडिंग जैसी चीजें भी हो सकती हैं (सबसे कपटी utf-8 है क्योंकि यह आम पात्रों के लिए ASCII जैसा दिखता है, लेकिन टर्मिनल द्वारा वैकल्पिक रूप से इसकी सेटिंग्स के आधार पर भी व्याख्या की जा सकती है, इसलिए यह अलग तरह से व्यवहार कर सकता है, फिर HTML की एन्कोडिंग विशेषता / XML, प्रक्रिया को ठीक से समझना आवश्यक है।

उदाहरण के लिए, कमांड लाइन में एक regexp perl -npe, फ़ाइल हैंडल को पाइप हैंडल के रूप में कनेक्ट करने वाले निष्पादन कॉल के एक सेट में स्थानांतरित करने की आवश्यकता है, इस निष्पादन प्रणाली कॉल में से प्रत्येक में उन तर्कों की एक सूची है जो (गैर-बच गए) रिक्त स्थान से अलग हो गए थे, और संभवत: पाइप (!) और पुनर्निर्देशन (> एन> एन> और एम), कोष्ठक, का *और अंतःक्रियात्मक विस्तार ?,$(())... (यह सभी विशेष वर्ण हैं जिनका उपयोग * sh द्वारा किया जाता है जो अगले संदर्भ में नियमित अभिव्यक्ति के चरित्र के साथ हस्तक्षेप कर सकते हैं, लेकिन उनका मूल्यांकन क्रम में किया जाता है: कमांड लाइन से पहले। कमांड लाइन को वाचन द्वारा पढ़ा जाता है। bash / sh / csh / tsh / zsh के रूप में कार्यक्रम, अनिवार्य रूप से दोहरे उद्धरण या एकल उद्धरण के अंदर बच सरल है लेकिन कमांड लाइन में एक स्ट्रिंग को उद्धृत करना आवश्यक नहीं है क्योंकि ज्यादातर स्थान को बैकस्लैश के साथ उपसर्ग करना पड़ता है और उद्धरण होते हैं वर्णों के लिए उपलब्ध कार्यक्षमता को छोड़ना आवश्यक नहीं है * और?, लेकिन यह उद्धरण के रूप में अलग-अलग संदर्भ के रूप में पार्स। तब जब कमांड लाइन का मूल्यांकन मेमोरी में प्राप्त regexp (कमांड लाइन में नहीं लिखा जाता है) के रूप में किया जाता है, तो इसे एक ही उपचार प्राप्त होता है। एक स्रोत फ़ाइल में होगा। regexp के लिए वर्ग कोष्ठक के भीतर वर्ण-सेट संदर्भ है [],perl रेगुलर एक्सप्रेशन को नॉन अल्फ़ा-न्यूमेरिक कैरेक्टर्स (जैसे m m // या m: / better / for / path: ...) के एक बड़े सेट द्वारा उद्धृत किया जा सकता है।

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



0

इओनिक (टाइपस्क्रिप्ट) के लिए आपको पात्रों को स्केप करने के लिए डबल स्लैश करना होगा। उदाहरण के लिए (यह कुछ विशेष पात्रों से मेल खाता है):

"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"

इस ] [ - _ . /चरित्र पर ध्यान दें । उन्हें दोहरी मार झेलनी पड़ती है। यदि आप ऐसा नहीं करते हैं, तो आपको अपने कोड में एक प्रकार की त्रुटि होने वाली है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.