Что делает \? средний в регулярном выражении?

Можно использовать волшебное пространство для расширения истории, прежде чем удар войдет. В Вашем .inputrc отобразите пространство на волшебное пространство:

$if Bash
     Space: magic-space
$endif

Теперь, каждый раз, когда Вы вводите пространство после спецификации истории, это будет сразу расширено - удобный, если Вы захотите отредактировать его, также!

16
05.11.2011, 23:02
3 ответа

Это похоже ? во многих других механизмах регулярного выражения, и означает "нуль соответствия или одно из того, что прибыло перед ним".

В Вашем примере, \? относится [ -], значение его пытается соответствовать пространству или минус, но что пространство или минус является дополнительным.

Таким образом, любой из них будет соответствовать:

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 \).

Дальнейшая информация:

21
27.01.2020, 19:48
  • 1
    egrep команда эквивалентна grep -E. Для версий кроме GNU grep, grep мог бы или не мог бы принять -E опция, и egrep могла бы быть отдельная программа. –  Keith Thompson 05.11.2011, 23:30
  • 2
    @KeithThompson, grep -E официальный POSIX путь. egrep был удержан от использования в susv2 (1997) и удален в susv3 (2001) от спецификаций Unix и POSIX. –  Stéphane Chazelas 08.12.2014, 02:50
  • 3
    \? GNUism все же. –  Stéphane Chazelas 08.12.2014, 02:51

К сожалению, точный синтаксис регулярных выражений варьируется немного между различными программами: grep regexes не являются точно тем же как sed regexes, которые не являются точно тем же как Emacs regexes, которые не являются точно тем же как C++ regexes и так далее. Для усугубления положения даже "стандартный" инструмент как grep может варьироваться немного между различными подобными Unix операционными системами.

В regex некоторые символы имеют особое значение (такое как квадратные скобки в Вашем примере) и возвращаются к их нормальному значению как буквенные символы, когда Вы "выходите" из них путем помещения обратной косой черты перед ними (таким образом, литеральная скобка была бы записана как \[). Другие работают наоборот и только берут особое значение при выходе (например, плоскость n является просто буквой, но \n является переводом строки). И они, снова, могут варьироваться между regex реализациями.

В большинстве regex реализаций вопросительный знак означает, что предыдущий объект является дополнительным, в то время как завершенный вопросительный знак (\?) литеральный вопросительный знак. Но на нескольких диалектах, это наоборот. Ваш пример мог иметь смысл так или иначе вокруг, но я подозреваю, что у Вас есть один из диалектов где? литерал и \? дополнительный символ. Таким образом, Ваш regex, вероятно, означает "три цифры, дополнительно сопровождаемые пространством или тире, сопровождаемым четырьмя цифрами".

(Другая подсказка видна в конструкциях как \{3\}, который ясно предназначается для значения "точно 3 из предыдущего объекта". На большинстве regex диалектов это было бы записано {3}, и \{будет литеральная фигурная скобка.)

8
27.01.2020, 19:48

Это - быстрая сводка информации, это уже содержится в других ответах.

В grep, ? соответствует литеральному символу вопросительного знака, и \? обозначает нуль или одно возникновение того, что предшествует ему. Таким образом в примере в Вашем вопросе, [ -]\? соответствия или пространство, или дефис или ничто.

В egrep или grep -E, это наоборот; \? соответствует литеральному вопросительному знаку, и ? обозначает нуль или одно возникновение.

Это относится к GNU grep; детали для не-GNU grep реализации могут отличаться немного. В частности, grep и egrep были исторически две отдельных программы, и я не думаю старый greps имел -E опция. POSIX действительно указывает grep -E, но (я был удивлен обнаружить), не упоминает egrep.

6
27.01.2020, 19:48

Теги

Похожие вопросы