อะไร \ หมายถึงการแสดงออกปกติ?


16

คำสั่งต่อไปนี้ใช้เพื่อค้นหาหมายเลขโทรศัพท์ 7 หลัก:

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

สิ่งที่\?ยืนหยัดเพื่อ?

คำตอบ:


21

มันเหมือนกับเอ็น?จิ้นนิพจน์ทั่วไปอื่น ๆ อีกมากมายและหมายถึง "จับคู่ศูนย์หรือหนึ่งในสิ่งใด ๆ ที่เกิดขึ้นมาก่อน"

ในตัวอย่างของคุณ\?จะใช้กับ[ -], หมายถึงพยายามจับคู่ช่องว่างหรือเครื่องหมายลบ แต่ช่องว่างหรือเครื่องหมายลบเป็นตัวเลือก

ดังนั้นสิ่งเหล่านี้จะจับคู่:

555 1234
555-1234
5551234

เหตุผลที่เขียน\?แทนที่จะ?เป็นเพื่อความเข้ากันได้ย้อนหลัง

เวอร์ชันเดิมของการgrepใช้นิพจน์ทั่วไปชนิดต่าง ๆ เรียกว่า "นิพจน์ทั่วไปขั้นพื้นฐาน" ซึ่ง?หมายถึงเครื่องหมายคำถามตามตัวอักษร

เพื่อให้ grep ของ GNU สามารถมีค่าเป็นศูนย์หรือหนึ่งฟังก์ชันได้ แต่เพิ่มเข้าไป แต่ต้องใช้\?ไวยากรณ์เพื่อให้สคริปต์ที่ใช้?ยังคงทำงานได้ตามที่คาดไว้

โปรดทราบว่า 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สำหรับรุ่นอื่นที่ไม่ใช่ greu GNU grepอาจจะหรืออาจจะไม่ยอมรับ-Eตัวเลือกและegrepอาจเป็นโปรแกรมแยกต่างหาก
Keith Thompson

@ KeithThompson grep -Eเป็นวิธี POSIX อย่างเป็นทางการ egrepถูกเลิกใช้ใน susv2 (1997) และลบออกใน susv3 (2001) จากข้อมูลจำเพาะ POSIX และ Unix
Stéphane Chazelas

1
\?เป็น GNUism แม้ว่า
Stéphane Chazelas

8

น่าเสียดายที่ไวยากรณ์ที่แน่นอนของนิพจน์ทั่วไปแตกต่างกันเล็กน้อยระหว่างโปรแกรมต่าง ๆ : grep regexes นั้นไม่เหมือนกับ sed regexes ซึ่งไม่เหมือนกับ emacs regexes ซึ่งไม่เหมือนกับ C ++ regexes อย่างแน่นอน บน. เพื่อให้เรื่องแย่ลงแม้แต่เครื่องมือ "มาตรฐาน" อย่าง grep อาจแตกต่างกันเล็กน้อยระหว่างระบบปฏิบัติการยูนิกซ์ที่แตกต่างกันเล็กน้อย

ใน regex อักขระบางตัวมีความหมายพิเศษ (เช่นวงเล็บเหลี่ยมในตัวอย่างของคุณ) และเปลี่ยนกลับไปเป็นความหมายปกติของพวกเขาเป็นตัวอักษรเมื่อคุณ "หลบหนี" พวกเขาโดยใส่เครื่องหมายแบ็กสแลชไว้ข้างหน้าพวกเขา เขียนเป็น \ [) คนอื่นทำงานในทางตรงกันข้ามและรับความหมายพิเศษเมื่อหนีออกมาเท่านั้น (เช่นธรรมดา n เป็นเพียงตัวอักษร แต่ \ n เป็นตัวดึงข้อมูลบรรทัด) และสิ่งเหล่านี้อีกครั้งสามารถแตกต่างกันระหว่างการใช้งาน regex

ในการใช้งาน regex ส่วนใหญ่เครื่องหมายคำถามหมายความว่ารายการก่อนหน้าเป็นทางเลือกในขณะที่เครื่องหมายคำถามแบบ Escape (\?) เป็นเครื่องหมายคำถามที่แท้จริง แต่ในอีกไม่กี่ภาษามันเป็นวิธีอื่น ตัวอย่างของคุณเข้าใจได้ทั้งสองทาง แต่ฉันคิดว่าคุณมีหนึ่งในภาษาถิ่นที่อยู่? เป็นตัวอักษรและ \? เป็นสัญลักษณ์เสริม ดังนั้น regex ของคุณอาจหมายถึง "สามหลักตามด้วยตัวเลือกเว้นวรรคหรือเส้นประตามด้วยตัวเลขสี่หลัก"

(เบาะแสอื่นสามารถเห็นได้ในโครงสร้างเช่น \ {3 \} ซึ่งมีความหมายชัดเจนว่าหมายถึง "3 จากรายการก่อนหน้านี้" อย่างชัดเจนในภาษาท้องถิ่นส่วนใหญ่ regex นี้จะเขียน {3} และ \ {จะเป็นวงเล็บที่แท้จริง .)


6

นี่เป็นข้อมูลสรุปโดยย่อที่มีอยู่แล้วในคำตอบอื่น ๆ

ในgrep, ?ตรงกับตัวอักษรเครื่องหมายคำถามตัวอักษรและ\?หมายถึงศูนย์หรือหนึ่งเกิดขึ้นของสิ่งที่นำหน้ามัน ดังนั้นในตัวอย่างในคำถามของคุณ[ -]\?จับคู่เว้นวรรคหรือยัติภังค์หรือไม่มีอะไรเลย

ในegrepหรือgrep -Eเป็นวิธีอื่น ๆ \?ตรงกับเครื่องหมายคำถามตามตัวอักษรและ?แสดงถึงศูนย์หรือหนึ่งเกิดขึ้น

สิ่งนี้ใช้กับ GNU grep; รายละเอียดสำหรับการใช้ grep ที่ไม่ใช่ของ GNU อาจแตกต่างกันเล็กน้อย โดยเฉพาะอย่างยิ่งgrepและegrepเป็นสองโปรแกรมที่แยกกันในอดีตและฉันไม่คิดว่าโปรแกรมตัวเก่าgrepจะมี-Eตัวเลือก POSIX ไม่ระบุgrep -Eแต่ (ฉันรู้สึกประหลาดใจที่จะค้นพบ) egrepไม่ได้พูดถึง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.