मेरी नियमित अभिव्यक्ति X में क्यों नहीं लेकिन Y में काम करती है?


76

मैंने एक नियमित अभिव्यक्ति लिखी जो एक निश्चित कार्यक्रम (grep, sed, awk, perl, python, ruby, ksh, bash, zsh, find, emacs, vi, vim, gedit,…) में अच्छी तरह से काम करती है। लेकिन जब मैं इसे एक अलग कार्यक्रम (या एक अलग यूनिक्स संस्करण पर) में उपयोग करता हूं, तो यह मेल खाना बंद कर देता है। क्यों?

जवाबों:


102

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

परिणाम यह है कि यदि आपके पास एक उपकरण में काम करने वाली एक नियमित अभिव्यक्ति है, तो आपको इसे किसी अन्य उपकरण में काम करने के लिए संशोधित करने की आवश्यकता हो सकती है। आम साधनों के बीच मुख्य अंतर हैं:

  • चाहे ऑपरेटरों +?|(){}को बैकस्लैश की आवश्यकता हो;
  • मूल से परे .[]*^$और आमतौर पर कौन से एक्सटेंशन समर्थित हैं+?|()

इस जवाब में, मैं मुख्य मानकों को सूचीबद्ध करता हूं । विवरण के लिए आपके द्वारा उपयोग किए जा रहे टूल के प्रलेखन की जांच करें।

विकिपीडिया की नियमित अभिव्यक्ति इंजनों की तुलना में सामान्य कार्यान्वयन द्वारा समर्थित सुविधाओं को सूचीबद्ध करने वाली एक तालिका है।

बुनियादी नियमित अभिव्यक्ति (BRE)

बेसिक रेगुलर एक्सप्रेशंस POSIX मानक द्वारा कोड किए गए हैं । यह सिंटैक्स द्वारा उपयोग किया जाता है grep, sedऔर vi। यह सिंटैक्स निम्नलिखित विशेषताएं प्रदान करता है:

  • ^और $केवल एक पंक्ति की शुरुआत और अंत में मिलान करें।
  • . किसी भी चरित्र (या एक नई पंक्ति को छोड़कर किसी भी चरित्र) से मेल खाता है।
  • […]कोष्ठक (वर्ण सेट) के अंदर सूचीबद्ध किसी एक वर्ण से मेल खाता है। यदि उद्घाटन ब्रैकेट के बाद पहला वर्ण ए है ^, तो जो वर्ण सूचीबद्ध नहीं हैं, वे इसके बजाय मेल खाते हैं। एक को शामिल करने के लिए ], इसे खोलने के तुरंत बाद डालें [(या [^यदि यह एक नकारात्मक सेट है)। यदि -दो वर्णों के बीच है, तो यह एक सीमा को दर्शाता है; शाब्दिक रूप से शामिल करने के लिए -, इसे एक सीमा के रूप में पार्स नहीं किया जा सकता है।
  • किसी भी ^$.*\[अगले वर्ण से पहले बैकस्लैश करें।
  • * पूर्ववर्ती वर्ण या उपसर्ग 0, 1 या अधिक बार मेल खाता है।
  • \(…\)*ऑपरेटर या बैकरेफेरेंस और \DIGITरिप्लेसमेंट के साथ उपयोग करने के लिए एक सिंथैटिक समूह है ।
  • Backreferences \1, \2…। इसी समूह द्वारा मिलान किए गए सटीक पाठ से मेल खाते हैं, जैसे \(fo*\)\(ba*\)\1मैच foobaafooलेकिन नहीं foobaafo। 10 वें समूह और उससे आगे का संदर्भ देने का कोई मानक तरीका नहीं है (मानक \10का पहला समूह है जिसके बाद 0)।

निम्नलिखित विशेषताएं भी मानक हैं, लेकिन कुछ प्रतिबंधित कार्यान्वयन से गायब हैं:

  • \{m,n\}मी से n के बीच के पूर्ववर्ती चरित्र या उपसंचाई से मेल खाता है ; n या m को छोड़ा जा सकता है, और इसका अर्थ है बिल्कुल m\{m\}
  • कोष्ठक के अंदर, वर्ण वर्गों का उपयोग किया जा सकता है, उदाहरण के लिए [[:alpha:]]किसी भी पत्र से मेल खाता है। ब्रैकेट एक्सप्रेशन के आधुनिक कार्यान्वयन ) में कोलिटिंग तत्व जैसे [.ll.]और समतुल्य वर्ग जैसे शामिल हैं [=a=]

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

  • \|प्रत्यावर्तन के लिए: foo\|barमाचिस fooया bar
  • \?(शॉर्ट फॉर \{0,1\}) और \+(शॉर्ट फॉर \{1,\}) क्रमशः 1 बार या कम से कम 1 बार पूर्ववर्ती चरित्र या उपसंचाई से मेल खाते हैं।
  • \nएक नई रेखा से मेल खाता है, \tएक टैब से मेल खाता है, आदि।
  • \wकिसी भी शब्द के घटक से मेल खाता है ( [_[:alnum:]]लेकिन स्थानीयकरण की बात होने पर भिन्नता के साथ) और ऐसे \Wकिसी भी चरित्र से मेल खाता है जो शब्द का कोई घटक नहीं है।
  • \<और \>खाली स्ट्रिंग का मिलान क्रमशः किसी शब्द की शुरुआत या अंत में करें; \bया तो मेल खाता है, और \Bजहाँ \bनहीं होता है।

ध्यान दें कि \|ऑपरेटर के बिना उपकरण में नियमित अभिव्यक्ति की पूरी शक्ति नहीं है। Backreferences कुछ अतिरिक्त चीजों को अनुमति देते हैं जो गणितीय अर्थों में नियमित अभिव्यक्तियों के साथ नहीं किया जा सकता है।

विस्तारित नियमित भाव (ERE)

विस्तारित नियमित अभिव्यक्ति POSIX मानक द्वारा संहिताबद्ध हैं । BRE पर उनका प्रमुख लाभ नियमितता है: सभी मानक ऑपरेटर नंगे विराम चिह्न वर्ण हैं, विराम चिह्नों से पहले एक बैकस्लैश वर्ण इसे उद्धृत करते हैं। यह सिंटैक्स द्वारा awk, grep -Eया egrep, GNU sed -rऔर बैश के=~ ऑपरेटर द्वारा उपयोग किया जाता है । यह सिंटैक्स निम्नलिखित विशेषताएं प्रदान करता है:

  • ^और $केवल एक पंक्ति की शुरुआत और अंत में मिलान करें।
  • . किसी भी चरित्र (या एक नई पंक्ति को छोड़कर किसी भी चरित्र) से मेल खाता है।
  • […]कोष्ठक (वर्ण सेट) के अंदर सूचीबद्ध किसी एक वर्ण से मेल खाता है। प्रारंभिक ^और श्रेणियों के साथ कार्यान्वयन BRE (जैसे ऊपर देखें) में काम करता है। चरित्र वर्ग का उपयोग किया जा सकता है लेकिन कुछ कार्यान्वयन से गायब हैं। आधुनिक कार्यान्वयन समतुल्यता वर्गों और कोलाजिंग तत्वों का भी समर्थन करते हैं। कोष्ठक के अंदर एक बैकस्लैश अगले वर्ण को कुछ में लागू करता है लेकिन सभी कार्यान्वयनों में नहीं; \\पोर्टेबिलिटी के लिए बैकस्लैश का उपयोग करने का मतलब है।
  • (…)के साथ *या \DIGITप्रतिस्थापन के लिए उपयोग करने के लिए एक वाक्य रचना समूह है ।
  • |प्रत्यावर्तन के लिए: foo|barमाचिस fooया bar
  • *, +और ?पूर्ववर्ती चरित्र या उपसंचाई से कई बार मेल खाता है: 0 या अधिक के लिए *, 1 या अधिक के लिए +, 0 या 1 के लिए ?
  • बैकस्लैश अगले वर्ण को उद्धृत करता है यदि यह अल्फ़ान्यूमेरिक नहीं है।
  • {m,n}मी और एन समय (कुछ कार्यान्वयन से गायब) के बीच पूर्ववर्ती चरित्र या उपप्रकारकता से मेल खाता है ; n या m को छोड़ा जा सकता है, और इसका अर्थ है बिल्कुल m{m}
  • BRE के रूप में कुछ सामान्य एक्सटेंशन: बैकरेफरेंस (व्यस्त बॉक्स कार्यान्वयन में जहां आप उपयोग कर सकते हैं ) को छोड़कर awk में अनुपस्थित हैं ; विशेष वर्ण , आदि; शब्द सीमाएँ और , शब्द घटक और …\DIGIT$0 ~ "(...)\\1"\n\t\b\B\b\B

PCRE (पर्ल-संगत नियमित अभिव्यक्ति)

पीसीआरई ईआरई का विस्तार है, जो मूल रूप से पर्ल द्वारा पेश किया गया है grep -Pऔर जीएनयू और कई आधुनिक उपकरणों और प्रोग्रामिंग भाषाओं द्वारा अपनाया गया है , आमतौर पर पीसीआरई पुस्तकालय के माध्यम से । उदाहरणों के साथ अच्छे प्रारूपण के लिए पर्ल दस्तावेज देखें । पर्ल के नवीनतम संस्करण की सभी विशेषताएं पीसीआरई द्वारा समर्थित नहीं हैं (जैसे पर्ल कोड निष्पादन केवल पर्ल में समर्थित है)। समर्थित सुविधाओं के सारांश के लिए पीसीआरई मैनुअल देखें । ERE के मुख्य जोड़ हैं:

  • (?:…)एक गैर-कैप्चरिंग समूह है: जैसे (…), लेकिन बैकरेफरेंस के लिए गिनती नहीं है।
  • (?=FOO)BAR(लुकहैड) मैच करता है BAR, लेकिन केवल तभी जब FOOउसी स्थिति में शुरू करने के लिए एक मैच भी होता है । यह मैच में निम्नलिखित पाठ को शामिल किए बिना मैच को एंकर करने के लिए सबसे उपयोगी है: foo(?=bar)मैच fooलेकिन केवल अगर इसके बाद bar
  • (?!FOO)BAR(नकारात्मक रूपांतर) से मेल खाता है BAR, लेकिन एक FOOही स्थिति के लिए एक मैच भी नहीं है । उदाहरण के लिए (?!foo)[a-z]+किसी भी निचले शब्द से मेल खाता है जो इसके साथ शुरू नहीं होता है foo; [a-z]+(?![0-9)किसी भी लोअरकेस शब्द से मेल खाता है, जो एक अंक (तो foo123, यह मेल खाता है, foलेकिन नहीं foo) द्वारा पीछा नहीं किया जाता है ।
  • (?<=FOO)BAR(तलाश) मैचों BAR, लेकिन केवल अगर यह तुरंत के लिए एक मैच से पहले है FOOFOOएक ज्ञात लंबाई होनी चाहिए (आप पुनरावृत्ति ऑपरेटरों का उपयोग नहीं कर सकते हैं जैसे *)। यह मैच में पूर्ववर्ती पाठ को शामिल किए बिना मैच को एंकर करने के लिए सबसे अधिक उपयोगी है: (?<=^| )fooमैच fooलेकिन केवल अगर यह किसी स्थान से पहले या स्ट्रिंग की शुरुआत से पहले हो।
  • (?<!FOO)BAR(नकारात्मक खोज) मैच BAR, लेकिन केवल अगर यह तुरंत एक मैच के लिए पहले से नहीं है FOOFOOएक ज्ञात लंबाई होनी चाहिए (आप पुनरावृत्ति ऑपरेटरों का उपयोग नहीं कर सकते हैं जैसे *)। यह मैच में पूर्ववर्ती पाठ को शामिल किए बिना मैच को एंकर करने के लिए सबसे उपयोगी है: (?<![a-z])fooमैच fooलेकिन केवल अगर यह लोअरकेस अक्षर से पहले नहीं है।

Emacs

Emacs का सिंटैक्स BRE और ERE के बीच मध्यवर्ती है। Emacs के अलावा, यह -regexGNU खोज के लिए डिफ़ॉल्ट सिंटैक्स है । Emacs निम्नलिखित ऑपरेटरों को प्रदान करता है:

  • ^, $, ., […], *, +, ?ERE में के रूप में
  • \(…\), \|, \{…\}, BRE में के रूप में\DIGIT
  • अधिक बैकलैश-अक्षर अनुक्रम ; \<और \>शब्द सीमाओं के लिए; Emacs के हाल के संस्करणों में और अधिक, जो अक्सर Emacs जैसे सिंटैक्स वाले अन्य इंजनों में समर्थित नहीं होते हैं।

खोल के दस्ताने

शेल ग्लब्स (वाइल्डकार्ड्स) एक वाक्यविन्यास से मेल खाने वाले पैटर्न का प्रदर्शन करते हैं जो नियमित अभिव्यक्तियों से पूरी तरह से अलग और कम शक्तिशाली है। गोले के अलावा, ये वाइल्डकार्ड अन्य उपकरणों जैसे कि find -nameऔर rsync फ़िल्टर के साथ उपलब्ध हैं । POSIX पैटर्न में निम्नलिखित विशेषताएं शामिल हैं:

  • ? किसी एक पात्र से मेल खाता है।
  • […]एक चरित्र है जो सामान्य नियमित अभिव्यक्ति सिंटैक्स में सेट किया गया है। कुछ गोले चरित्र वर्गों का समर्थन नहीं करते हैं। सेट को नकारने के !बजाय कुछ गोले की आवश्यकता होती है ^
  • *वर्णों के किसी भी क्रम से मेल खाता है (अक्सर /फ़ाइल पथों के मिलान के अलावा ; यदि /इसे बाहर रखा गया है *, तो **कभी-कभी इसमें शामिल हैं /, लेकिन उपकरण के दस्तावेज़ की जांच करें)।
  • बैकलैश ने अगला किरदार उद्धृत किया।

Ksh अतिरिक्त सुविधाएँ प्रदान करता है जो इसके पैटर्न को नियमित अभिव्यक्ति की पूर्ण शक्ति से मेल खाते हैं। ये फीचर रनिंग के बाद बैश में भी उपलब्ध हैं shopt -s extglob। Zsh का एक अलग सिंटैक्स है लेकिन बाद में ksh के सिंटैक्स का भी समर्थन कर सकता है setopt ksh_glob


अन्य अमीर आरईएस जिनका आप उल्लेख करना चाहते हैं, वे vimएटी एंड टी लिबास (जैसा कि ksh93) हैं।
स्टीफन चेजलस

@ स्टीफनचेज़ेलस, विम के अलावा, किस प्रोग्राम में वीआईएम रीजैक्स का उपयोग किया जाता है? Ksh के अलावा, कौन से प्रोग्राम में लिबास का उपयोग होता है?
गिलीस

एटी एंड टी उपकरण सेट के सभी एटी एंड टी आर ई (का उपयोग करता है grep, tw, expr...)। को छोड़कर ksh, उस टूलसेट को शायद ही कभी एटी एंड टी के बाहर पाया जाता है।
स्टीफन चेज़लस

मेरी समझ (और विकिपीडिया) के अनुसार, आपका शब्द "चरित्र वर्ग" वास्तव में "पोसिक्स चरित्र वर्ग" को संदर्भित करता है ... हालांकि, regex(7)आपसे सहमत है और [these]"ब्रैकेट एक्सप्रेशन" और ("ब्रैकेट एक्सप्रेशन" के भीतर) [:these:]"चरित्र वर्ग।" मुझे यकीन नहीं है कि कैसे सबसे अच्छा पता है।
एडम काटज़

आप उन्हें जो भी कहते हैं, वे पर्वतमाला का समर्थन करते हैं। यह निश्चित रूप से ध्यान देने योग्य है कि -एक सीमा को निर्दिष्ट करता है और या तो बच जाना चाहिए, पहले (वैकल्पिक के बाद ^), या आखिरी अगर यह सचमुच लिया जाना है। (मैंने उदाहरण के लिए बहुत से कीड़े देखे हैं [A-z], जो केस-टू में बदलाव से मेल खाते हैं, जो 65 से 122 के कोड के पात्रों से मेल खाते हैं और गलती से प्रत्येक में शामिल हैं: [\]^_`मैंने यह भी देखा है कि मान्य अभी तक [!-~]ANSI के सभी प्रिंट करने योग्य वर्णों से मेल खाते हैं। , जिसे मैं [\x21-\x7e]अलग-अलग आयामों में भ्रामक होते हुए भी अपनी कार्रवाई में कम से कम सीधा देखना पसंद करता हूं ।)
एडम काट्ज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.