如何量化 POSIX 扩展正则表达式?

Cru*_*se5 0 bash regular-expression

  1. 密码应以大写字母开头
  2. 密码应包含小写字母
  3. 密码应包含数字
  4. 密码长度应至少为 8 且少于 16 个字符

我想在 bash 脚本中使用 POSIX 字符类,并且我有以下内容(它不起作用)。我不知道如何分组才能满足长度条件。

^[[:upper:]][[:lower:]]+[[:upper:]]*[[:digit:]]+$ {8,15} 应该去哪里?

Sté*_*las 5

POSIX 扩展正则表达式没有“and”运算符,也没有环视运算符,因此要构建一个能够积极验证这些密码的正则表达式,您需要构建一个数千个字符长的正则表达式,其中列出了小数和数字和数字的所有组合之间的字符,例如:

u='[[:upper:]]' l='[[:lower:]]' d='[[:digit:]]'
regexp="^$u(($l$d|$d$l).{5,12}|($d.$l|.$d$l|$l.$d|.$l$d).{4,11}|...etc...)\$"
Run Code Online (Sandbox Code Playgroud)

它太长了,您可能会达到系统正则表达式引擎的某些限制。

在这里,匹配多个正则表达式会更容易:

valid_password=(
  '^[[:upper:]]'
  '[[:lower:]]'
  '[[:digit:]]'
  '^.{8,15}$'
)
validate_password() {
  local regexp
  for regexp in "${valid_password[@]}"; do
    [[ $1 =~ $regexp ]] || return
  done
}

if validate_password "$some_password"; then
  echo OK
fi
Run Code Online (Sandbox Code Playgroud)

然而,使用一个正则表达式进行否定匹配会更容易:

incorrect='^([^[:upper:]].*|[^[:digit:]]*|[^[:lower]]*|.{0,7}|.{16,})$'
Run Code Online (Sandbox Code Playgroud)

(如果以大写字母以外的字符开头,或者完全由非数字或非小写字母组成,或者由 0 到 7 个字符或 16 个或更多字符组成,则不正确)。

如果[[ $password =~ $incorrect ]]返回true,则说明密码不正确。但是,如果它返回 false,也可能是因为$password包含不形成有效字符的字节序列,因此您还需要添加一个检查,以在[[ $password =~ ^.*$ ]]声明密码有效之前验证密码是否由有效字符组成。

如果可以选择从 切换bashzsh,则可以使用具有一些环视运算符的 PCRE,这将使事情变得更容易:

set -o rematchpcre
[[ $password =~ '^(?=.*\d)(?=.*\p{Ll})\p{Lu}.{7,14}\Z' ]]
Run Code Online (Sandbox Code Playgroud)

请注意,如果$password语言环境中的文本无效,则会失败(返回 false)并报告错误。请注意,PCRE 不支持 UTF-8 以外的多字节编码。

另请注意,zsh 中的变量可以包含 NUL 字符,PCRE API 与 POSIX ERE API 不同,不会因这些字节而阻塞,但您可能希望拒绝密码中的这些字符以及所有其他控制字符(包括换行符) )。

(请注意,我还没有测试过这些)