Почему символ регулярного выражения «?» не дает совпадения в sed?

Почему символ регулярного выражения «?» не дает совпадения в sed?

У меня есть строка, похожая на ../../sdd1и пытаюсь сопоставить sddотсюда. Я пытаюсь использовать следующую sedкоманду:

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]?:\1:' 

и это не дает совпадений.
Но когда я использую

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'

затем я получаю свою спичку, sdd.

Я думаю, что мне следует экранировать ?также, как и фигурные скобки — я попробовал, и это работает, но я не знаю почему.

Итак, вопрос в том, почему [0-9]?регулярное выражение не соответствует 1from sdd1или почему нам приходится экранировать the ?и фигурные скобки?

решение1

По умолчанию sedиспользуется BRE, и потребуется -Eили -rопция для использования ERE

Цитата изРуководство по GNU sed

В GNU sed единственное различие между базовыми и расширенными регулярными выражениями заключается в поведении нескольких специальных символов: «?», «+», скобок, фигурных скобок («{}») и «|».

В базовом синтаксисе (BRE) эти символы не имеют специального значения, если перед ними не стоит обратная косая черта ('\'); В расширенном синтаксисе (ERE) все наоборот: эти символы являются специальными, если перед ними не стоит обратная косая черта ('\').

так, для GNU sed, используйте

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\?:\1:'
sdd
$ echo '../../sdd1' | sed -E 's:.*([a-z]{3})[0-9]?:\1:'
sdd

дляPOSIX BRE, ваша вторая команда - это путь

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'
sdd

Связанный контент