我已经为此工作了一段时间,访问了数十个网站并尝试了各种组合;但是,我无法让脚本按预期运行。即使他们工作在https://regex101.com/,我仍然无法让它们在 bash 中工作。
我正在尝试编写一个 bash 脚本,该脚本将验证输入(“$password”)的长度至少为八个字符,并且至少包含一个数字和至少一个以下特殊字符:#?!@$ %^&* -
GNU bash,版本 5.1.16(1)-release-(x86_64-pc-linux-gnu)
任何帮助将不胜感激!
read -p "Please enter a password to test: " password
echo "You entered '$password'"
# I have tried all of the following (plus a few others) and cannot get it to work
#regex='^[a-zA-Z0-9#@$?]{8,}$'
#regex='^[a-zA-Z0-9@#$%&*+-=]{8,}$'
#regex='^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@#$%&*+-=]).{8,}$'
#regex='^(?=.*?[a-zA-Z0-9])(?=.*?[#?!@$ %^&*-]).{8,}$'
#regex='^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[#?!@$ %^&*-]).{8,}$'
if [[ $password =~ $regex ]]; then
echo "This works"
else
echo "Nope"
fi
答案1
支持的扩展正则表达式语法bash
缺乏构造在多个子表达式之间执行布尔 AND 测试的单个表达式的能力。因此,您可以更轻松地对每种条件执行一次测试。
您的字符串似乎需要满足三个条件:
- 至少八个字符。
- 至少一位数字(我认为您所说的“数字”就是这个意思)。
- 该组中至少有一个角色
#?!@$ %^&*-
。
这意味着三个测试:
if [ "${#password}" -ge 8 ] &&
[[ $password == *[[:digit:]]* ]] &&
[[ $password == *[#?!@$\ %^\&*-]* ]]
then
echo 'good'
else
echo 'not good'
fi
在最后的测试中,一些特殊字符必须被转义。我们可以通过使用变量让它看起来更漂亮:
has_digit='*[[:digit:]]*'
has_special='*[#?!@$ %^&*-]*' # or possibly '*[[:punct:]]*'
if [ "${#password}" -ge 8 ] &&
[[ $password == $has_digit ]] &&
[[ $password == $has_special ]]
then
echo 'good'
else
echo 'not good'
fi
请注意,我在这里没有使用正则表达式,而是使用普通的 shell 模式。匹配的集合[[:punct:]]
是稍大的“标点符号”集合(特别不包含空格字符,但您可以使用[[:punct:] ]
or[[:punct:][:blank:]]
或[[:punct:][:space:]]
):
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
如果您确实只需要使用正则表达式,那么请执行以下操作
has_8='.{8}'
has_digit='[[:digit:]]'
has_special='[#?!@$ %^&*-]' # or possibly '[[:punct:]]'
if [[ $password =~ $has_8 ]] &&
[[ $password =~ $has_digit ]] &&
[[ $password =~ $has_special ]]
then
echo 'good'
else
echo 'not good'
fi
注意改变的模式。
关于该站点的一般警告regex101.com
是,它并未声称专门支持大多数标准 Unix 文本处理工具使用的 POSIX 正则表达式,而仅支持这些正则表达式的各种扩展变体。
答案2
作为一个选项:
if [ ! "${password/????????*}" -a\
"$password" != "${password/[0-9]}" -a\
"$password" != "${password/[#?!@$ %^&*-]}" ]
then
echo "This works"
else
echo "Nope"
fi
但据我记得,验证提供了小写和大写字母的存在,这意味着您需要更改:
if [ ! "${password/????????*}" -a\
"$password" != "${password/[a-z]}" -a\
"$password" != "${password/[A-Z]}" -a\
"$password" != "${password/[0-9]}" -a\
"$password" != "${password/[#?!@$ %^&*-]}" ]