Использование FreeBSD 11.1:
#!/bin/sh
if printf 'abcde.fgh' | grep -iEq '^[^][$^*_-]'; then
echo "test 1 success"
else
echo "test 1 fail"
fi
echo
if printf 'abcde.fgh' | grep -iEq '^[^][.$^*_-]'; then
echo "test 2 success"
else
echo "test 2 fail"
fi
Выход:
test 1 success
grep: Unmatched [ or [^
test 2 fail
Но AFAICT они должны давать тот же результат. Они оба содержат условие на первый символ (только), что он не входит в список указанных неалфавитных символов. Разбивка регулярного выражения:
^
= начало строки[^...]
= совпадение, если ни один из этих символов не соответствует- В списке
]
должен быть первым символом,^
не должен быть первым, и - должен быть последним. Таков][.^$_-
допустимый список литеральных символов, и строка не должна совпадать ни с одним из них. - Во избежание путаницы следует отметить, что это означает, что в списке
][
присутствуют литералы"]"
и символы,"["
нетзакрытие и повторное открытие 2 списков.
Единственное различие между этими двумя выражениями заключается в том, "."
что оно находится внутри списка, поэтому его следует рассматривать как not literal .
и, действительно, первый символ не соответствует литералу."."
Что я упускаю? Наверное, что-то очень очевидное и простое?
решение1
Вы упускаете несколько других правил синтаксиса. В расширении скобок, в дополнение к простым диапазонам, есть также несколько типов многосимвольных выражений, которые начинаются с [
. (См.регулярное выражение(7)руководство дляЛинуксилиFreeBSDв "За исключением этихи некоторые комбинации с использованием '['(см. следующие параграфы)".) Это:
- Элементы подбора:
[.
….]
- Классы эквивалентности:
[=
…=]
- Классы персонажей:
[:
…:]
(Вы могли видеть или использовать такие выражения, как [[:digit:]]
– на самом деле это класс символов [:digit:]
, который является единственным элементом […]
раскрытия скобок.)
Так что в вашем случае, поскольку .
находится сразу после a [
, они распознаются как открывающий разделитель элемента сортировки. GNU grep 3.1 выдает правильное сообщение об ошибке:
$ printf 'abcde.fgh' | grep -iEq '^[^][.$^*_-]'
grep: Unmatched [, [^, [:, [., or [=
Те же выражения можно использовать для выхода из подобных ситуаций, используя, например, [...]
или [=.=]
для включения обычной точки, или аналогичным образом [=-=]
для сопоставления с тире, если их некуда переместить.