क्या करता है \? एक नियमित अभिव्यक्ति में?


16

7-अंकीय फ़ोन नंबर खोजने के लिए निम्न कमांड का उपयोग किया जाता है:

grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file

किसलिए \?खड़ा है?

जवाबों:


21

यह पसंद है ? कई अन्य नियमित अभिव्यक्ति इंजनों है, और इसका मतलब है "शून्य या जो भी इसके पहले आया था" में से एक का मिलान करें।

आपके उदाहरण में, के \?लिए लागू किया गया है[ -] , जिसका अर्थ है कि यह अंतरिक्ष या माइनस से मेल खाने की कोशिश करता है, लेकिन यह कि स्पेस या माइनस वैकल्पिक है।

तो इनमें से कोई भी मैच करेगा:

555 1234
555-1234
5551234

कारण यह लिखा है के \?बजाय? पीछे संगतता के लिए है।

grepएक अलग प्रकार की नियमित अभिव्यक्ति के मूल संस्करण को "मूल नियमित अभिव्यक्ति" कहा जाता है, जहां ?सिर्फ एक शाब्दिक प्रश्न चिह्न होता है।

ताकि GNU grep में शून्य या एक कार्यक्षमता हो सके, उन्होंने इसे जोड़ा, लेकिन इसका उपयोग करना था \? सिंटैक्स ताकि स्क्रिप्ट जो ?अभी भी उम्मीद के मुताबिक काम कर सके।

ध्यान दें कि grep में एक -Eविकल्प होता है जो इसे अधिक सामान्य प्रकार के नियमित अभिव्यक्ति का उपयोग करता है, जिसे "विस्तारित नियमित अभिव्यक्ति" कहा जाता है।

man 1 grep:

   -E, --extended-regexp
          Interpret PATTERN as an extended regular expression
          (ERE, see below).  (-E is specified by POSIX.)

   -G, --basic-regexp
          Interpret PATTERN as a basic regular expression (BRE, see below).
          This is the default.

...

Repetition
    A regular expression may be followed by one of several repetition operators:
    ?      The preceding item is optional and matched at most once.

...

    grep understands three different versions of regular expression syntax:
    “basic,” “extended” and “perl.”

...

Basic vs Extended Regular Expressions
    In basic regular expressions the meta-characters ?, +, {, |, (, and )
    lose their special meaning; instead use the backslashed versions
    \?, \+, \{, \|, \(, and \).

आगे की जानकारी:


egrepआदेश के बराबर है grep -E। GNU grep के अलावा अन्य संस्करणों के लिए, विकल्प को grepस्वीकार या नहीं भी कर सकते हैं -E, और egrepएक अलग कार्यक्रम हो सकता है।
कीथ थॉम्पसन

@KeithThompson, grep -Eआधिकारिक POSIX तरीका है। egrepsusv2 (1997) में पदावनत किया गया था और POSIX और यूनिटी स्पेक्स से susv3 (2001) में हटा दिया गया था।
स्टीफन चेज़लस

1
\?हालांकि एक GNUism है।
स्टीफन चेज़लस

8

दुर्भाग्य से, नियमित अभिव्यक्ति का सटीक सिंटैक्स अलग-अलग कार्यक्रमों के बीच थोड़ा भिन्न होता है: grep regexes ठीक उसी प्रकार नहीं है जैसे कि sed regexes, जो कि Emacs regexes के समान नहीं हैं, जो कि C ++ rexxes के समान नहीं हैं, और इसलिए पर। मामलों को बदतर बनाने के लिए, यहां तक ​​कि grep जैसा "मानक" उपकरण विभिन्न यूनिक्स जैसे ऑपरेटिंग सिस्टमों के बीच थोड़ा भिन्न हो सकता है।

एक रेगेक्स में, कुछ वर्णों का विशेष अर्थ होता है (जैसे कि आपके उदाहरण में वर्ग कोष्ठक), और उनके सामान्य अर्थ के रूप में वापस आते हैं जब आप उनके सामने एक बैकस्लैश लगाकर "बच" जाते हैं (तो शाब्दिक ब्रैकेट होगा) के रूप में लिखा है []। अन्य लोग दूसरे तरीके से काम करते हैं, और बच निकलने पर केवल विशेष अर्थ लेते हैं (जैसे कि सादे n सिर्फ एक अक्षर है, लेकिन \ n एक पंक्ति फ़ीड है)। और ये, फिर से, रेगेक्स कार्यान्वयन के बीच भिन्न हो सकते हैं।

अधिकांश रेगेक्स कार्यान्वयन में, एक प्रश्न चिह्न का मतलब है कि पिछला आइटम वैकल्पिक है, जबकि एक बचा हुआ प्रश्न चिह्न (\?) एक शाब्दिक प्रश्न चिह्न है। लेकिन कुछ बोलियों में, यह दूसरा तरीका है। आपका उदाहरण किसी भी तरह से समझ में आ सकता है, लेकिन मुझे संदेह है कि आपके पास बोलियों में से एक कहाँ है? एक शाब्दिक और है? वैकल्पिक प्रतीक है। तो आपके रेगेक्स का अर्थ है "तीन अंक, वैकल्पिक रूप से एक स्थान या डैश, उसके बाद चार अंक"।

(एक अन्य सुराग \ _ \ _ 3) जैसे निर्माणों में देखा जा सकता है, जिसका स्पष्ट अर्थ "पिछली वस्तु का ठीक 3" है। अधिकांश रीजेक्स बोलियों में यह {3} लिखा जाएगा, और \ {एक शाब्दिक ब्रेस होगा। ।)


6

यह जानकारी का एक त्वरित सारांश है जो पहले से ही अन्य उत्तरों में निहित है।

में grep, ?एक शाब्दिक प्रश्न-चिह्न चरित्र से मेल खाता है, और \?जो कुछ भी इसके पूर्व में शून्य या एक घटना को दर्शाता है। तो आपके प्रश्न में उदाहरण में [ -]\?, या तो एक स्थान, या एक हाइफ़न, या कुछ नहीं से मेल खाता है।

में egrepया grep -E, यह दूसरी तरह के आसपास है, \?एक शाब्दिक प्रश्न चिह्न से मेल खाता है, और ?शून्य या एक घटना को दर्शाता है।

यह GNU grep पर लागू होता है; गैर-जीएनयू जीआरईपी कार्यान्वयन के लिए विवरण थोड़ा भिन्न हो सकते हैं। विशेष रूप से, grepऔर egrepऐतिहासिक रूप से दो अलग-अलग कार्यक्रम थे, और मुझे नहीं लगता कि पुराने grepएस के पास -Eविकल्प था। POSIX निर्दिष्ट करता है grep -E, लेकिन (मुझे पता नहीं चला) आश्चर्यचकित था egrep

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