
У меня есть строка, похожая на ../../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]?
регулярное выражение не соответствует 1
from 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