我想创建一个密码输入模板,条件是:
- 密码长度必须至少为 12 个字符;
- 必须至少有1个小写字母、1个大写字母、1个数字、1个特殊字符;
- 特定的特殊字符如<>``````~不允许;
- 顺序无所谓,只要满足前面3个条件即可。
我已经利用负前瞻来创建一个模式,但这不起作用。我的模式:
^(.{0,11}|[^0-9]*|[^A-Z]*|[^a-z]*|[a-zA-Z0-9<>~`|"\']*|[^\s]*\s.*)$
操作系统:Ubuntu 20.04
答案1
你的问题没有提到你如何尝试使用你的表达方式。 shell中的正则表达式bash
是 POSIX 扩展正则表达式。这些不支持正向或负向前瞻或后向查看。
我建议不要使用您的表达式来尝试将更多内容融入其中,而是将测试分解为几个单独的测试。
如果每个测试都是独立完成的,那么最容易理解实现并保持它的维护,而不是试图制作一个怪物表达式来完成这一切。
#!/bin/bash
pw_is_valid () {
local avoid='[<>`"'"'"'~]'
[ "${#1}" -ge 12 ] &&
[[ $1 =~ [[:upper:]] ]] &&
[[ $1 =~ [[:lower:]] ]] &&
[[ $1 =~ [[:digit:]] ]] &&
[[ $1 =~ [[:punct:]] ]] &&
[[ ! $1 =~ $avoid ]]
}
until
IFS= read -r -s -p 'Enter password: ' pw
pw_is_valid "$pw"
do
echo 'Try again' >&2
done
我使用变量avoid
来保存正则表达式,[<>`"'~]
以减少表示它所需的引用。
在POSIX
akaC
语言环境中,POSIX[:punct:]
字符类包含以下字符集中的字符:
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
在常规区域中,它通常会包含更多内容。
我在这里用它作为“特殊字符”的替代品。
1 例如,在 Ubuntu 20.04 和 en_GB.UTF-8 语言环境中,它包含 147495 个不同的字符。 YMMV 取决于系统、版本和区域设置。