Perintah berikut digunakan untuk mencari nomor telepon 7 digit:
grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file
Apa artinya \?
?
Perintah berikut digunakan untuk mencari nomor telepon 7 digit:
grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file
Apa artinya \?
?
Jawaban:
Ini seperti ?
di banyak mesin ekspresi reguler lainnya, dan berarti "cocok dengan nol atau apa pun yang datang sebelumnya".
Dalam contoh Anda, \?
diterapkan pada [ -]
, artinya mencoba mencocokkan ruang atau minus, tetapi ruang atau minus itu opsional.
Jadi semua ini akan cocok:
555 1234
555-1234
5551234
Alasan mengapa ini ditulis \?
bukan ?
untuk kompatibilitas.
Versi asli dari grep
menggunakan berbagai jenis ekspresi reguler yang disebut "ekspresi reguler dasar" di mana ?
hanya berarti tanda tanya literal.
Supaya GNU grep dapat memiliki fungsi nol atau satu, mereka menambahkannya, tetapi harus menggunakan \?
sintaks sehingga skrip yang digunakan ?
masih berfungsi seperti yang diharapkan.
Perhatikan bahwa grep memiliki -E
opsi yang membuatnya menggunakan jenis ekspresi reguler yang lebih umum, yang disebut "extended regular expressions".
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 \).
Info lebih lanjut:
grep -E
adalah cara POSIX resmi. egrep
dihentikan pada susv2 (1997) dan dihapus pada susv3 (2001) dari spesifikasi POSIX dan Unix.
\?
adalah GNUisme.
Sayangnya, sintaks yang tepat dari ekspresi reguler bervariasi sedikit antara program yang berbeda: grep regexes tidak persis sama dengan regex sed, yang tidak persis sama dengan regex Emacs, yang tidak persis sama dengan regex C ++, dan sebagainya di. Lebih buruk lagi, bahkan alat "standar" seperti grep dapat sedikit berbeda antara sistem operasi mirip Unix.
Dalam sebuah regex, beberapa karakter memiliki arti khusus (seperti tanda kurung siku dalam contoh Anda), dan kembali ke makna normalnya sebagai karakter literal ketika Anda "melarikan diri" dengan meletakkan garis miring terbalik di depannya (sehingga braket literal akan menjadi ditulis sebagai \ [). Yang lain bekerja sebaliknya, dan hanya mengambil arti khusus ketika lolos (mis. Polos n hanya huruf, tetapi \ n adalah umpan baris). Dan ini, sekali lagi, dapat bervariasi antara implementasi regex.
Di sebagian besar implementasi regex, tanda tanya berarti bahwa item sebelumnya adalah opsional, sedangkan tanda tanya yang lolos (\?) Adalah tanda tanya literal. Tetapi dalam beberapa dialek, itu sebaliknya. Contoh Anda bisa masuk akal, tetapi saya curiga Anda memiliki salah satu dialek di mana? itu literal dan \? adalah simbol opsional. Jadi regex Anda mungkin berarti "tiga digit, opsional diikuti oleh spasi atau tanda hubung, diikuti oleh empat digit".
(Petunjuk lain dapat dilihat dalam konstruksi seperti \ {3 \}, yang jelas dimaksudkan untuk berarti "tepat 3 dari item sebelumnya". Dalam kebanyakan dialek regex ini akan ditulis {3}, dan \ {akan menjadi penjepit literal .)
Ini adalah ringkasan informasi yang sudah terkandung dalam jawaban lain.
Di grep
, ?
cocok dengan karakter tanda tanya literal, dan \?
menunjukkan nol atau satu kejadian dari apa pun yang mendahuluinya. Jadi, dalam contoh dalam pertanyaan Anda, [ -]\?
cocok dengan spasi, atau tanda hubung, atau tidak sama sekali.
Di egrep
atau grep -E
, itu sebaliknya; \?
cocok dengan tanda tanya literal, dan ?
menunjukkan nol atau satu kejadian.
Ini berlaku untuk GNU grep; detail untuk implementasi grep non-GNU mungkin sedikit berbeda. Secara khusus, grep
dan egrep
secara historis dua program terpisah, dan saya tidak berpikir tua grep
punya -E
pilihan. POSIX tidak menentukan grep -E
, tetapi (saya terkejut menemukan) tidak menyebutkan egrep
.
egrep
perintah setara dengangrep -E
. Untuk versi selain GNU grep,grep
mungkin atau mungkin tidak menerima-E
opsi, danegrep
mungkin program terpisah.