Sed में नियमित अभिव्यक्ति में [\ w] + का उपयोग कैसे करें?


24

मैं विंडोज पर हूं, लेकिन मुझे लगता है कि मेरा सवाल अभी भी यहीं रखा गया है।

C:\Users\User>grep --version
GNU grep 2.6.3

C:\Users\User>sed --version
GNU sed version 4.2.1

मैंने देखा कि निम्नलिखित कार्य (आउटपुट here):

echo here | grep -E "\w+"
echo here | grep -E "[her]+"

लेकिन, यह काम नहीं करता है (कुछ भी नहीं उत्पादन):

echo here | grep -E "[\w]+"

यह फिर से करता है (आउटपुट here):

echo here | grep -P "[\w]+"

तो [\w]पर्ल नियमित अभिव्यक्ति के लिए कुछ विशिष्ट है, मुझे लगता है। क्या वो सही है?

तो, चलिए बात करते हैं sed। यह काम करता है (आउटपुट gone):

echo here | sed -r "s/\w+/gone/"
echo here | sed -r "s/[her]+/gone/"

और फिर, यह (आउटपुट here) नहीं करता है :

echo here | sed -r "s/[\w]+/gone/"

अब, मैं कैसे sed के लिए Perl नियमित अभिव्यक्तियों को सक्रिय कर सकता हूं - क्या कोई तरीका है?

जवाबों:


11

इसके विभिन्न उपकरण और संस्करण नियमित अभिव्यक्ति के विभिन्न रूपों का समर्थन करते हैं। प्रत्येक का प्रलेखन आपको बताएगा कि वे क्या समर्थन करते हैं।

मानक मौजूद हैं ताकि सभी सुविधाओं के एक न्यूनतम सेट पर भरोसा कर सकें जो सभी अनुरूप अनुप्रयोगों में उपलब्ध हैं।

उदाहरण के लिए, के सभी आधुनिक कार्यान्वयन sedऔर grepके रूप में POSIX द्वारा निर्दिष्ट (कम से कम एक संस्करण या मानक के अन्य, लेकिन यह मानक पिछले कुछ दशकों में इस संबंध में एक बहुत विकसित नहीं किया गया है) बुनियादी नियमित अभिव्यक्ति लागू।

POSIX BRE और ERE में, आपके पास [:alnum:]वर्ण वर्ग है। यह आपके लोकेल में अक्षरों और अंकों से मेल खाता है (ध्यान दें कि अक्सर इसमें बहुत अधिक शामिल होता है a-zA-Z0-9जब तक कि लोकेल सी नहीं हो)।

इसलिए:

grep -x '[[:alnum:]_]\{1,\}'

एक या अधिक अलंकरण या _ से मेल खाता है।

[\w]POSIX द्वारा बैकस्लैश या मैच के लिए आवश्यक है w। तो तुम एक नहीं मिलेगा grepया sedकार्यान्वयन जहां कि उपलब्ध है (जब तक के माध्यम से गैर मानक विकल्प)।

\wअकेले के लिए व्यवहार POSIX द्वारा निर्दिष्ट नहीं है, इसलिए कार्यान्वयन को वे जो चाहते हैं करने की अनुमति है। जीएनयू grepने कहा कि बहुत पहले।

GNU grepमें अपना स्वयं का regexp इंजन होता था, लेकिन अब यह GNU libc का उपयोग करता है (हालाँकि यह अपनी प्रति एम्बेड करता है)।

यह आपके लोकेल में अलनम्स और अंडरस्कोर का मिलान करने के लिए है। हालाँकि, वर्तमान में यह एक बग है कि यह केवल एकल-बाइट वर्णों से मेल खाता है (उदाहरण के लिए, UTF-8 लोकेल में नहीं, भले ही यह स्पष्ट रूप से एक अक्षर है और भले ही यह उन सभी स्थानों में मेल खाता हो, जहां é एक है चरित्र)।

\wPerl regexp और PCRE में एक regexp ऑपरेटर भी है । PCRE / perl POSIX नियमित अभिव्यक्ति नहीं हैं, वे पूरी तरह से एक और चीज हैं।

अब, जिस तरह से जीएनयू grep -Pपीसीआरई का उपयोग करता है, यह बिना किसी मुद्दे के समान है -P। इसका उपयोग करके यद्यपि वहाँ काम किया जा सकता है (*UCP)(हालाँकि गैर-UTF8 स्थानों में इसके दुष्प्रभाव भी हैं)।

GNU sedअपने स्वयं के regexps के लिए GNU libc के रेगेक्स का भी उपयोग करता है। यह इसे इस तरह से उपयोग करता है, हालांकि इसमें GNU के समान बग नहीं है grep

GNU sedPCREs का समर्थन नहीं करता है। कोड में कुछ साक्ष्य हैं जिन्हें पहले प्रयास किया गया है, लेकिन यह अब एजेंडा में नहीं है।

यदि आप पर्ल के नियमित भाव चाहते हैं, तो बस उपयोग करें perl

अन्यथा, मैं कहूंगा कि आपके sed/ के विशेष कार्यान्वयन के फर्जी गैर-मानक विशेषता पर भरोसा करने के बजाय grepमानक और उपयोग के साथ रहना बेहतर होगा [_[:alnum:]]


[_[:alnum:]]एक अच्छा समाधान है जो मुझे इसे [\w/]( [_[:alnum:]/]उस स्थिति में) की तरह विस्तारित करने की अनुमति देता है ।
BERS

1
यह उत्तर अब जीएनयू की सीमाओं के संबंध में पुराना है grep
स्टीफन चेज़लस

7

आप सही हैं - \wपीसीआरई का एक हिस्सा है - पर्ल संगत नियमित अभिव्यक्ति। यह हालांकि 'मानक' रेगेक्स का हिस्सा नहीं है। http://www.regular-expressions.info/posix.html

कुछ संस्करण sedइसका समर्थन कर सकते हैं, लेकिन मैं सुझाव दूंगा कि झंडा निर्दिष्ट करके मोड perlमें उपयोग करना सबसे आसान तरीका है । (साथ में )। (अधिक में )sed-p-eperlrun

लेकिन आपको []उस उदाहरण में इसकी आवश्यकता नहीं है - यह मान्य सामान के समूहों के लिए है।

echo here  | perl -pe 's/\w+/gone/'

या विंडोज पर:

C:\>echo here  | perl -pe "s/\w+/gone/"
gone
C:\>echo here  | perl -pe "s/[\w\/]+/gone/"
gone

perlreअधिक पीसीआरई सामान के लिए देखें ।

आप यहाँ पर पर्ल प्राप्त कर सकते हैं: http://www.activestate.com/activeperl/downloads


कृपया मेरे प्रश्न में \wऔर [\w]मेरे बीच के अंतर पर ध्यान दें । मैं इसे स्पष्ट करने के लिए प्रत्येक कमांड के आउटपुट के साथ अपडेट करूंगा कि कौन सा काम कर रहा है और कौन सा नहीं। विशेष रूप से, sedसमझता है \w, लेकिन नहीं [\w]। इसके अलावा, मुझे [\w]काम करने की आवश्यकता है क्योंकि मैं [\w/]उदाहरण के लिए उपयोग करना चाहता हूं ।
BERS

किस मामले में, यह शायद एक उद्धृत समस्या है। किसी भी तरह से - perlयह कर सकते हैं :)।
सोब्रीक

धन्यवाद! स्टीफन चेज़लस का उत्तर मेरे द्वारा पूछे जाने के बाद से थोड़ा सा करीब है (क्योंकि मेरे पास पर्ल स्थापित नहीं है - एक du * b विंडोज उपयोगकर्ता, मुझे लगता है), इसलिए मैंने उनका उत्तर स्वीकार कर लिया।
BERS

यह ठीक है - लेकिन मैं विंडोज पर पर्ल स्थापित करने की सलाह दूंगा। यह पहली चीजों में से एक है जो मेरा काम करता है, और मुझे यह बहुत मददगार लगता है।
सब्रीक

\wजीएनयू ग्रीप में था (80 के दशक में) पर्ल में होने से पहले और जीएनयू एमएसीएस में शायद उससे पहले भी।
स्टीफन चेज़लस

1

मुझे लगता है कि संदेह है grepऔर sedजब लागू करने के लिए अलग तरह से निर्णय लेने से कर रहे हैं []और जब विस्तार करने के लिए \w। पर्ल रेगेक्स में \wकिसी भी शब्द वर्ण का अर्थ है, और []एक मैच के रूप में किसी भी वर्ण को लागू करने के लिए एक समूह को परिभाषित करें। यदि आप \wपहले "विस्तार" करते हैं तो []यह सभी शब्द वर्णों का एक वर्ण वर्ग होगा। यदि, इसके बजाय आप []पहले करते हैं तो आपके पास दो वर्णों के साथ एक वर्ण वर्ग होगा \और wइसलिए यह उन दो वर्णों में से एक या एक से अधिक पैटर्न से मेल खाएगा।

तो ऐसा लगता है कि sedहै देखकर []और के रूप में मैच के लिए सही वर्ण युक्त बजाय विशेष अनुक्रम का सम्मान में यह इलाज \wके रूप में perlऔर grepकरते हैं। बेशक, []इस उदाहरण में पूरी तरह से अनावश्यक हैं, लेकिन कोई ऐसे मामलों की कल्पना कर सकता है जहां यह महत्वपूर्ण होगा, लेकिन फिर आप इसे पारेंस और ओआरएस के साथ काम कर सकते हैं।


मुझे आश्चर्य होगा अगर ऐसा था। \ एक पलायन कोड है, और आप इसे सीमांकक से बचने के लिए उपयोग करेंगे। निहित रूप से इसका मतलब है कि किसी भी चीज की तुलना में इसका उच्च स्तर होना है। मुझे लगता है कि यह अधिक संभावना है कि इसे लागू नहीं किया गया है क्योंकि \wनियमित अभिव्यक्ति युक्ति का हिस्सा नहीं है
सोब्रीक

खैर, आनुभविक रूप से यह मेरे लिए ग्नू सेड का उपयोग करने के मामले में लगता है: मुझे echo whe\\ere | sed -r 's/[\w]+/gone/gदेता है gonehegoneereजैसे कि यह प्रत्येक में से प्रत्येक से मेल ` and खा रहा है और प्रतिस्थापन कर रहा है
एरिक

मैं पुष्टि कर सकता हूं कि एरिक रेनॉफ क्या देख रहा है। तो हम किसी भी तरह बैकस्लैश को हटाना चाहते हैं? :)
BERS

मुझे नहीं लगता कि यह सही उत्तर है। Sed सिर्फ विभिन्न प्रकार के वर्ण वर्ग की परिभाषाओं को मिलाने का समर्थन नहीं करता है, इसलिए इसका उत्तर यह है कि यदि आपको दोनों प्रकार के वर्ण वर्गों का उपयोग करना चाहिए तो कोई अन्य उपकरण चुनें, या यदि आप sed का उपयोग कर रहे हैं तो यह वाक्य रचना का उपयोग करता है
एरिक रेनॉफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.