Регулярное выражение ^[[:alnum:]]*[[:alpha:]][[:alnum:]]*$
не проверяет числа отдельно, так как [:alnum:]
также соответствует буквам. [:alpha:]
должно быть подмножеством [:alnum:]
, поэтому шаблон соответствует любой строке, состоящей только из букв и цифр, по крайней мере, с одной буквой.
(Предполагая обычное жадное сопоставление, если ввод abcd
, то abc
будет соответствовать [[:alnum:]]*
, окончательное d
будет соответствовать [[:alpha:]]
, а последнее [[:alnum:]]*
не будет соответствовать. (нужно )соответствовать чему угодно.)
Если вы хотите проверить, что строка содержит хотя бы одну букву и одну цифру, проще разделить ее на две проверки, т.е. проверку на [[:alpha:]]
и[[:digit:]]
:
if [[ $str =~ [[:alpha:]] && $str =~ [[:digit:]] ]]; then
echo "contains a letter and a digit"
Если вы также хотите отклонять строки, которые содержат что-либо еще (, например знаки препинания ), добавьте для этого проверку:
if [[ $str =~ [[:alpha:]] && $str =~ [[:digit:]] && ! $str =~ [^[:alnum:]] ]]; then
echo "contains a letter and a digit, but no non-alphanumerics"
Чтобы найти неудачные случаи, инвертируйте весь тест с помощью !
в начале(if ! [[...
).
(Чтобы сделать это с помощью одного регулярного выражения, вы можете использовать что-то вроде этого:^([[:alnum:]]*[[:alpha:]][[:alnum:]]*[[:digit:]][[:alnum:]]*|[[:alnum:]]*[[:digit:]][[:alnum:]]*[[:alpha:]][[:alnum:]]*)$
но это немного ужасно )