Відповіді:
Це як ?
у багатьох інших двигунах регулярної експресії, і означає "відповідати нулю або одному, що було раніше".
У вашому прикладі, файл \?
застосовується до [ -]
значення, тобто він намагається відповідати пробілу або мінусу, але пробіл або мінус необов’язковий.
Отже, будь-яке з них буде відповідати:
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 \).
Додаткова інформація:
grep -E
є офіційним способом POSIX. egrep
був припинений у susv2 (1997) та видалений у susv3 (2001) із специфікацій POSIX та Unix.
\?
- це GNUism.
На жаль, точний синтаксис регулярних виразів дещо різниться між різними програмами: grep-регулярні вирази не точно такі, як sed-регулярні вирази, які не точно такі, як регекси Emacs, які не точно такі, як C ++ -вище, і так на. Що ще гірше, навіть такий «стандартний» інструмент, як grep, може дещо відрізнятися між різними операційними системами, схожими на Unix.
У регулярному вираженні деякі символи мають особливе значення (наприклад, квадратні дужки у вашому прикладі) і повертаються до свого нормального значення, як буквальні символи, коли ви «рятуєтесь» від них, ставлячи зворотній косу рису (таким чином, буквальна дужка була б записується як \ [). Інші працюють навпаки і набувають особливого значення лише під час втечі (наприклад, звичайний n - це лише літера, але \ n - канал рядка). І це, знову ж таки, може змінюватись між реалізаціями регулярних виразів.
У більшості застосувань регулярних виразів знак питання означає, що попередній елемент необов’язковий, тоді як уникнутий знак питання (\?) - це буквальний знак питання. Але в кількох діалектах - навпаки. Ваш приклад може мати сенс у будь-якому випадку, але я підозрюю, що у вас є один із діалектів? є буквальним і \? - необов'язковий символ. Тож ваш регулярний вираз, ймовірно, означає "три цифри, необов'язково - пробіл або тире, а потім чотири цифри".
(Інший підказку можна побачити в таких конструкціях, як \ {3 \}, що, очевидно, означає "рівно 3 попереднього пункту". У більшості діалектних регексів це буде написано {3}, а \ {буде буквальною дужкою .)
Це швидкий підсумок інформації, який вже міститься в інших відповідях.
В grep
, ?
збігається з буквальним символом знака питання і \?
позначає нуль або один випадок того, що йому передує. Тож у прикладі у вашому запитанні [ -]\?
збігається пробіл, або дефіс, або нічого.
У egrep
або grep -E
, навпаки; \?
відповідає буквальному знаку запитання і ?
позначає нуль або один випадок.
Це стосується GNU grep; деталі для нереалізованих grep-реалізацій можуть незначно відрізнятися. Зокрема, grep
і egrep
були історично дві окремих програми, і я не думаю , що старий grep
s мав -E
варіант. POSIX вказує grep -E
, але (я здивовано виявив) не згадує egrep
.
egrep
Команда еквівалентнаgrep -E
. Для версій, відмінних від GNU grep,grep
може бути або не приймати цей-E
варіант, і цеegrep
може бути окрема програма.