Как вы используете символ плюс с классом символов как часть регулярного выражения? - PullRequest
4 голосов
/ 13 апреля 2011

в cygwin это не возвращает совпадение:

$ echo "aaab" | grep '^[ab]+$'

Но это возвращает совпадение:

$ echo "aaab" | grep '^[ab][ab]*$'
aaab

Разве два выражения не идентичны?Есть ли способ выразить «один или несколько символов класса символов», не вводя класс символов дважды (как в примере с секундами)?

Согласно этой ссылке два выражения должныбыть тем же, но, возможно, Regular-Expressions.info не охватывает bash в cygwin.

Ответы [ 3 ]

7 голосов
/ 13 апреля 2011

grep имеет несколько «режимов» сопоставления и по умолчанию использует только базовый набор, который не распознает количество метасимволов, если они не экранированы.Вы можете перевести grep в расширенный режим или режим Perl, чтобы оценить +.

С man grep:

Matcher Selection
  -E, --extended-regexp
     Interpret PATTERN as an extended regular expression (ERE, see below).  (-E is specified by POSIX.)

  -P, --perl-regexp
     Interpret PATTERN as a Perl regular expression.  This is highly experimental and grep -P may warn of unimplemented features.


Basic vs Extended Regular Expressions
  In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).

  Traditional egrep did not support the { meta-character, and some egrep implementations support \{ instead, so portable scripts should avoid { in grep -E patterns and should use [{] to match a literal {.

  GNU  grep -E attempts to support traditional usage by assuming that { is not special if it would be the start of an invalid interval specification.  For example, the command grep -E '{1' searches for the two-character string {1 instead of reporting a syntax
       error in the regular expression.  POSIX.2 allows this behavior as an extension, but portable scripts should avoid it.

В качестве альтернативы, вы можете использовать egrep вместо grep -E.

6 голосов
/ 13 апреля 2011

В основных регулярных выражениях метасимволы ?, +, {, |, ( и ) потерять свое особое значение; вместо этого используйте версии с обратной косой чертой \ ?, \+, \{, \|, \( и \).

Так что используйте версию с обратной косой чертой:

$ echo aaab | grep '^[ab]\+$'
aaab

Или активировать расширенный синтаксис:

$ echo aaab | egrep '^[ab]+$'
aaab
2 голосов
/ 13 апреля 2011

Маскирование обратной косой чертой или egrep как расширенный grep, псевдоним grep -e:

echo "aaab" | egrep '^[ab]+$'

AAAB

echo "aaab" | grep '^[ab]\+$'

AAAB

...