Что я здесь сделал не так?
Попытка сопоставить любую строку, содержащую пробелы, строчные, прописные буквы или числа. Специальные символы тоже были бы хороши, но я думаю, что для этого нужно экранировать определенные символы.
TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#"
if [[ "$TEST" =~ [^a-zA-Z0-9\ ] ]]; then BLAH; fi
Очевидно, это проверяет только верхние, нижние, числа и пробелы. Но не работает.
* ОБНОВИТЬ *
Думаю, мне следовало быть более конкретным. Вот настоящая строчка кода.
if [[ "$TITLE" =~ [^a-zA-Z0-9\ ] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; fi
* ОБНОВИТЬ *
./anm.sh: line 265: syntax error in conditional expression
./anm.sh: line 265: syntax error near `&*#]'
./anm.sh: line 265: ` if [[ ! "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; return; fi'
regex
bash
if-statement
Атомиклан
источник
источник
re='...whatever...'; [[ $string =~ $re ]]
(без кавычек - это один из редких случаев, когда сломают то, что без них работало бы).[[ $var =~ .* ]]
для регулярного выражения соответствия.*
(что угодно). Я предполагаю, что если вы используете кавычки, сами кавычки считаются частью регулярного выражения…pattern='^hello[0-9]*$'
(2.) в двойном квадрате выражения, если вам нужно сопоставление регулярных выражений, НЕ цитируйте шаблон, потому что цитирование ОТКЛЮЧАЕТ сопоставление шаблонов регулярных выражений. (т.е. выражение[[ "$x" =~ $pattern ]]
будет соответствовать с использованием регулярного выражения, а выражение[[ "$x" =~ "$pattern" ]]
отключает сопоставление регулярных выражений и эквивалентно[[ "$x" == "$pattern" ]]
).Ответы:
Есть несколько важных вещей, которые нужно знать о
[[ ]]
конструкции bash . Первое:Второе:
Следовательно,
$v
с обеих сторон=~
будет расширено до значения этой переменной, но результат не будет разбит по словам или расширен по имени пути. Другими словами, совершенно безопасно оставлять расширения переменных без кавычек с левой стороны, но вы должны знать, что расширения переменных будут происходить с правой стороны.Так что если вы пишете:
[[ $x =~ [$0-9a-zA-Z] ]]
, то$0
в регулярном выражении по праву будет расширены до регулярного выражения интерпретируется, который, вероятно , вызовет регулярное выражение , чтобы не компилировать (если не указано расширение$0
целей с символом цифр или знаков препинания , чье ASCII значения меньше цифра). Если вы процитируете правую часть таким образом[[ $x =~ "[$0-9a-zA-Z]" ]]
, то правая часть будет рассматриваться как обычная строка, а не как регулярное выражение (и$0
все равно будет расширена). Что вам действительно нужно в этом случае, так это[[ $x =~ [\$0-9a-zA-Z] ]]
Точно так же выражение между
[[
и]]
разбивается на слова перед интерпретацией регулярного выражения. Поэтому пробелы в регулярном выражении необходимо экранировать или заключать в кавычки. Если вы хотите , чтобы соответствовать буквы, цифры и пробелы вы можете использовать:[[ $x =~ [0-9a-zA-Z\ ] ]]
. Другие символы также должны быть экранированы, например#
, если они не указаны в кавычках, начнется комментарий. Конечно, вы можете поместить шаблон в переменную:pat="[0-9a-zA-Z ]" if [[ $x =~ $pat ]]; then ...
Многие люди предпочитают этот стиль для регулярных выражений, которые содержат множество символов, которые необходимо экранировать или заключать в кавычки для прохождения через лексер bash. Но будьте осторожны: в этом случае вы не можете указывать расширение переменной:
# This doesn't work: if [[ $x =~ "$pat" ]]; then ...
Наконец, я думаю, что вы пытаетесь проверить, что переменная содержит только допустимые символы. Самый простой способ выполнить эту проверку - убедиться, что он не содержит недопустимого символа. Другими словами, такое выражение:
valid='0-9a-zA-Z $%&#' # add almost whatever else you want to allow to the list if [[ ! $x =~ [^$valid] ]]; then ...
!
отменяет тест, превращая его в оператор «не соответствует», а[^...]
класс символов регулярного выражения означает «любой символ кроме...
».Комбинация операторов расширения параметров и регулярных выражений может сделать синтаксис регулярных выражений bash «почти читаемым», но все же есть некоторые подводные камни. (Не существует всегда?) Во- первых, вы не могли бы поставить
]
в$valid
, даже если$valid
были указаны, за исключением самого начала. (Это правило регулярного выражения Posix: если вы хотите включить]
в класс символов, он должен идти в начале.-
Может идти в начале или в конце, поэтому, если вам нужны оба]
и-
, вам нужно начинать]
и заканчивать с-
, что приводит к регулярному выражению «Я знаю , что я делаю» смайлик:[][-]
)источник
if ! [[ $x =~ $y ]]
либоif [[ ! $x =~ $y ]]
SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.
[[
и]]
» анализируются из текста программы точно так же, как командные строки разбираются на слова. Однако, в отличие от командных строк, слова не разделяются после раскрытия.Если кому-то нужен пример с использованием переменных ...
#!/bin/bash # Only continue for 'develop' or 'release/*' branches BRANCH_REGEX="^(develop$|release//*)" if [[ $BRANCH =~ $BRANCH_REGEX ]]; then echo "BRANCH '$BRANCH' matches BRANCH_REGEX '$BRANCH_REGEX'" else echo "BRANCH '$BRANCH' DOES NOT MATCH BRANCH_REGEX '$BRANCH_REGEX'" fi
источник
Я бы предпочел использовать
[:punct:]
для этого. Такжеa-zA-Z09-9
может быть просто[:alnum:]
:[[ $TEST =~ ^[[:alnum:][:blank:][:punct:]]+$ ]]
источник