सही regex grep में काम नहीं कर रहा है


13

मैं इस regex है:

(?<=prefix).*$

जो स्ट्रिंग "प्रीफिक्स" के बाद किसी भी चरित्र को लौटाता है और यह किसी भी ऑनलाइन रेगेक्स इंजन (जैसे https://regex101.com ) पर ठीक काम करता है । समस्या यह है कि जब मैं उस regex को bash में उपयोग करता हूं:

grep '(?<=prefix).*$' <<< prefixSTRING

यह कुछ भी मेल नहीं खाता है। क्यों कि रेगेक्स जीआरईपी के साथ काम नहीं करता है?


11
यह वास्तव में हाइलाइट करता है कि regex101 को जेएस, पर्ल / पीएचपी और पाइथन के लिए पोसिक्स स्वाद चयनकर्ता की आवश्यकता क्यों है। मैं उस समय की संख्या की गणना नहीं कर सकता, जिसके लिए मैंने कामना की है।
जेरेड स्मिथ


इसके अलावा, .*$किसी भी स्ट्रिंग का अंत-लाइन (या एंड-ऑफ-स्ट्रिंग) से मेल खाता है, न कि केवल किसी एक वर्ण से।
ilkachachu

जवाबों:


38

आपको लगता है कि आपने सही रेगेक्स को परिभाषित किया है, लेकिन grepइसे समझने के लिए कमांड-लाइन में पर्याप्त झंडे नहीं लगाए हैं । क्योंकि डिफ़ॉल्ट रूप से grepBRE का समर्थन करता है और -Eध्वज के साथ यह ERE करता है। आपके पास क्या है (लुक-अहिदे) केवल पीसीआरई रेगेक्स फ्लेवर में उपलब्ध है जो केवल जीएनयू grepमें अपने -Pझंडे के साथ समर्थित है ।

यह मानते हुए कि आपको केवल मिलान वाले स्ट्रिंग को निकालने की आवश्यकता है क्योंकि prefixआपको अतिरिक्त ध्वज जोड़ने की आवश्यकता है ताकि आपको -oपता चल सके grepकि केवल मिलान वाले भाग को प्रिंट करें

grep -oP '(?<=prefix).*$' <<< prefixSTRING

grepडिफ़ॉल्ट रूप से PCRE पुस्तकालयों का समर्थन करने वाला एक संस्करण भी है - pcregrepजिसमें आप बस कर सकते हैं

pcregrep -o '(?<=prefix).*$' <<< prefixSTRING

विभिन्न रेगेक्स जायकों पर विस्तृत विवरण इस अद्भुत जाइल्स के उत्तर और उपकरणों में समझाया गया है जो उनमें से प्रत्येक को लागू करते हैं


38

नियमित अभिव्यक्ति कई अलग-अलग स्वादों में आती हैं। आप जो दिखा रहे हैं वह एक पर्ल-रेगुलर एक्सप्रेशन (PCRE, "पर्ल कम्पेटिबल रेगुलर एक्सप्रेशन") है।

grepPOSIX नियमित अभिव्यक्ति करता है। ये मूल नियमित अभिव्यक्तियाँ हैं (BRE) और विस्तारित नियमित अभिव्यक्तियाँ (ERE, यदि विकल्प के grepसाथ प्रयोग किया जाता है -E)। मैनुअल re_formatया regexउसके समान या जो कुछ भी आपके grepमैनुअल को संदर्भित करता है, उसे अपने सिस्टम, या POSIX मानक ग्रंथों से देखें जो मैं अभी जुड़ा हुआ हूं।

यदि आप जीएनयू का उपयोग करते हैं grep, तो आप grepजीएनयू- grepविशिष्ट -Pविकल्प के साथ पर्ल-जैसे नियमित अभिव्यक्तियों का उपयोग करने में सक्षम होंगे ।

यह भी ध्यान दें कि लाइनें डिफ़ॉल्ट रूप से grepलौटती हैं , लाइनों से सब्सट्रिंग नहीं। फिर से, जीएनयू grep(और कुछ अन्य grepकार्यान्वयन) के साथ, आप -oकेवल बिट (ओं) को प्राप्त करने के लिए विकल्प का उपयोग कर सकते हैं जो प्रत्येक पंक्ति से दिए गए अभिव्यक्ति से मेल खाते हैं।

ध्यान दें कि दोनों -Pऔर -oअमानक एक्सटेंशन हैं की POSIX विनिर्देशनgrep

यदि आप GNU का उपयोग नहीं कर रहे हैं grep, तो आप sedस्ट्रिंग prefixऔर पंक्ति के अंत के बीच बिट प्राप्त करने के बजाय उपयोग कर सकते हैं :

sed -n 's/.*prefix\(.*\)/\1/p' file

यह क्या करता है केवल उन पंक्तियों को प्रिंट करना है जो sedदिए गए प्रतिस्थापन को लागू करने का प्रबंधन करता है। प्रतिस्थापन पूरे लाइन को बदल देगा जो अभिव्यक्ति से मेल खाता है (जो कि एक BRE है), इसके टुकड़े के साथ जो स्ट्रिंग के बाद होता है prefix

ध्यान दें कि यदि prefixएक पंक्ति में कई उदाहरण हैं , तो sedभिन्नता पिछले एक के बाद स्ट्रिंग लौटा देगी , जबकि GNU grepभिन्नता पहले एक के बाद स्ट्रिंग को लौटा देगी (जिसमें अन्य उदाहरण शामिल होंगे prefix)।

sedसमाधान सभी यूनिक्स सिस्टम के लिए पोर्टेबल होगा।


6

जैसा कि अन्य उत्तरों में कहा गया है, grepलुकहाइंड्स के साथ रेगेक्स स्वाद का उपयोग नहीं करता है (जीएनयू के साथ डिफ़ॉल्ट रूप से grep, या अन्य संस्करणों के साथ बिल्कुल भी नहीं)।

यदि आप अपने आप को GNU का उपयोग करने में असमर्थ पाते हैं grepया pcregrep, perlयदि आपके पास है तो आप इसका उपयोग कर सकते हैं ।

कमांड लाइन समतुल्य perlहोगी:

perl -ne 'print if /(?<=prefix).*$/' <<< prefixSTRING

आप स्लैश के बीच वांछित रेगेक्स डालते हैं। जैसा कि आप पर्ल का उपयोग कर रहे हैं, यह पर्ल के रेगेक्स स्वाद का उपयोग करता है ।


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