Почему эти регулярные выражения в 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-совместимости и ожидает, что будет вести себя аналогично.