我正在尝试检查 Linux 上的 shell 脚本,如果STR
包含“仅字母”或包含“仅数字”,则该脚本退出。如果STR
同时包含数字和字母,它应该通过。并且不包含特殊字符。
我正在尝试类似的方法,但它只能部分起作用。
#!/bin/sh
STR=$1
if [[ ! $STR =~ ^[[:alnum:]]*[[:alpha:]][[:alnum:]]*$ ]]; then
echo "The input must contain both digits and alphabets like abc123"
exit 1
fi
echo "Success"
exit 0
该检查部分有效,即STR
仅包含数字。但如果STR
包含所有字母则不起作用。我不想仅在包含字母和数字(如or )exit 1
时才执行。STR
abc123
ABC123
STR
如果包含则检查失败abc
。
如何在仅STR
包含时abc
和仅STR
包含时使检查工作123
?
答案1
您不需要在这里使用复杂的正则表达式。您有两个条件,因此使用两个测试:
if [[ $str == *[[:digit:]]* ]] &&
[[ $str == *[[:alpha:]]* ]]
then
printf '"%s" contains both letters and digits\n' "$str"
else
printf '"%s" lacks either letters or digits\n' "$str"
fi
您还提到了“特殊字符”,但没有具体说明这些字符是什么。假设您的意思是与 匹配的字符[[:punct:]]
,并且您不想要这些在字符串中,你可以使用
if [[ $str == *[[:digit:]]* ]] &&
[[ $str == *[[:alpha:]]* ]] &&
[[ $str != *[[:punct:]]* ]]
then
printf '"%s" contains both letters and digits, and no specials\n' "$str"
else
printf '"%s" lacks either letters or digits, or contains specials\n' "$str"
fi
[[:punct:]]
将匹配字符串中的任何一个字符
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
答案2
正则表达式^[[: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:]]*)$
但这有点可怕)
答案3
尝试让它变得更简单。将问题分成两部分:
...
if [[ $STR =~ ([a-zA-Z]+) && $STR =~ ([0-9]+) ]]; then
...