Имеет ли значение порядок в расширенных регулярных выражениях с []? - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь понять синтаксис [] с расширенными регулярными выражениями в grep.

Следующие два шаблона эквивалентны:

$ echo "foo_bar" | grep -E "[a-z_]+$"     
foo_bar
$ echo "foo_bar" | grep -E "[_a-z]+$" 
foo_bar

Однако эти два не являются:

$ echo "foobar[]" | grep -E "[a-z_\[\]]+$" 
foobar[]
$ echo "foobar[]" | grep -E "[a-z\[\]_]+$"

Почему это?Это где-нибудь задокументировано?Я ничего не видел в man grep об этом.

1 Ответ

0 голосов
/ 23 октября 2018

Вы должны быть осторожны при использовании двойных кавычек " и обратной косой черты \, поскольку BASH сначала обрабатывает обратную косую черту.Это изменит ваше регулярное выражение на [a-z_[]]+$.Однако все еще есть тонкость, и в оставшейся части этого вопроса я предполагаю, что вы использовали одинарные кавычки.

В первом случае у вас есть группа символов [a-z_\[\], которая соответствует символам a-z, _, \, [.Последний \] не перечисляет ] в качестве другого символа группы символов, а представляет собой \ и закрывающую скобку класса символов.Обратите внимание, как:

$ echo "foobar[]" | grep -E '[a-z\[\]+\]+$'
foobar[]
$ echo '\' | grep -E '[\]$'
\

Если вы хотите добавить ], вы должны сначала перечислить его, то есть []] соответствует одному ].

$ echo "]" | grep -E '[]]$'
]

Дляссылка см. man grep:

Чтобы включить литерал], поместите его первым в списке.Точно так же, чтобы включить литерал ^ поместите его где угодно, но не первым.Наконец, чтобы включить литерал - поместите его последним.

, а также https://www.regular -expressions.info / charclass.html

InВ большинстве разновидностей регулярных выражений единственными специальными символами или метасимволами внутри класса символов являются закрывающая скобка], обратная косая черта \, символ ^ и дефис -.Обычные метасимволы - это обычные символы внутри класса символов, и их не нужно экранировать обратной косой чертой.Чтобы найти звезду или плюс, используйте [+ *].Ваше регулярное выражение будет работать нормально, если вы избежите обычных метасимволов внутри класса символов, но это значительно снижает читабельность.

Еще больше тестовых случаев для проверки [\s] (что совпадает с [s\]и отличается от [[:space:]]):

$ echo 'a ' | grep -E 'a[\s]$'
$ echo 's' | grep -E '[\s]$'
s
$ echo '\' | grep -E '[\s]$'
\
$ echo 'a ' | grep -E 'a[[:space:]]$'
a

Итак, вывод таков: порядок не имеет значения при перечислении символов класса символов, за исключением случаев, когда он имеет значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...