Почему эти регулярные выражения в grep ведут себя странно?

Я хотел немного поиграть с grep используйте регулярные выражения и выясните, что они ведут себя не так, как я ожидал. Например, для файла temp со следующим содержанием

helloworld 
hello_world
hello world
hello how are you world
hello wor   ld
hello_*_..world 
helloEworld

когда я бегу

grep 'hello.*world' temp

это возвращается

helloworld 
hello_world
hello world
hello how are you world
hello_*_..world 
helloEworld

как и ожидалось. Но когда я бегу

grep 'hello.+world' temp

ничего не возвращает... хотя при добавлении \ до +

grep 'hello.\+world' temp

он возвращает правильный ответ

hello_world
hello world
hello how are you world
hello_*_..world 
helloEworld

при добавлении \ до * в предыдущей команде и работает

grep 'hello.\*world' temp

ничего не возвращает...

Почему эта команда grep 'hello.+world' temp не работает, тогда как с \ оно работает. И почему это как раз наоборот *? Когда я должен использовать \?

1 ответ

Решение

Существуют различные классы регулярных выражений, которые GNU grep поддерживает:

  • Основные регулярные выражения (BRE) - по умолчанию. Не поддерживает + напрямую, но поддерживает *, Ты можешь сделать + имеет смысл, когда вы избежите этого \+, Из документации GNU grep:

    In basic regular expressions the meta-characters ‘?’, ‘+’, ‘{’, ‘|’,
    ‘(’, and ‘)’ lose their special meaning; instead use the backslashed
    versions ‘\?’, ‘\+’, ‘\{’, ‘\|’, ‘\(’, and ‘\)’.
    
  • Расширенные регулярные выражения (ERE) - опция -E позволяет это. Поддерживает оба + а также * непосредственно.

  • Perl-совместимые регулярные выражения (PCRE) - -P опция включает PCRE. Поддерживает синтаксис, похожий на Perl, такой как lookaheads и lookbehinds.

BRE и ERE обычно являются стандартными классами, определенными POSIX, поэтому вы должны найти их в любом grep который стремится к POSIX-совместимости и ожидает, что будет вести себя аналогично.

Другие вопросы по тегам