【发布时间】:2011-05-11 22:30:18
【问题描述】:
如何在 BASH 脚本中使用以下正则表达式?
(?=^.{8,255}$)((?=.*\d)(?!.*\s)(?=.*[A-Z])(?=.*[a-z]))^.*
我需要检查以下用户输入(密码):
- 至少一个大写字母。
- 至少一个数字。
- 至少一个小写字母。
- 密码长度应介于 8 到 255 个字符之间。
【问题讨论】:
标签: regex bash input passwords
如何在 BASH 脚本中使用以下正则表达式?
(?=^.{8,255}$)((?=.*\d)(?!.*\s)(?=.*[A-Z])(?=.*[a-z]))^.*
我需要检查以下用户输入(密码):
【问题讨论】:
标签: regex bash input passwords
我不认为您的正则表达式是检查列表中内容的最佳(或正确?)方法(提示:我会独立于其他条件检查长度),但要回答关于在Bash中使用的问题:使用grep -Eq的返回值,例如:
if echo "$candidate_password" | grep -Eq "$strong_pw_regex"; then
echo strong
else
echo weak
fi
或者在 Bash 3 及更高版本中,您可以使用 =~ 运算符:
if [[ "$candidate_password" =~ "$strong_pw_regex" ]]; then
…
fi
grep -E 或 Bash 的正则表达式语法不一定支持您在示例中使用的所有内容,但可以检查您的要求。但是如果你想要更高级的正则表达式,你可能需要用 Ruby 或 Perl 之类的东西来代替 Bash。
至于修改您的正则表达式,请使用 Bash 检查长度(${#candidate_password} 会为您提供变量 candidate_password 中字符串的长度),然后使用没有前瞻的简单语法。为简单起见,您甚至可以使用单独的正则表达式检查所有三个条件。
【讨论】:
echo-weak 应该是一个新标签...去it's-always-friday-in-iceland旁边
ruby 或perl,如果这不是问题的话,类似于调用grep。或者,如果您的意思是纯 Bash,请使用 =~(假设您可以假设 Bash 3.x 最低),但您需要修改您的正则表达式(grep 也是如此)。
[a-z]、[A-Z] 和 [0-9]。
grep 和 -E 选项使用扩展正则表达式 (ERE)
从此documentation ERE 不支持前瞻。
因此,您可以将 Perl 用作:
perl -ne 'exit 1 if(/(?=^.{8,255}$)((?=.*\\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*/);exit 0;'
【讨论】:
【讨论】:
这些匹配是用逻辑 AND 运算符连接的,这意味着唯一好的匹配是当它们都匹配时。 因此,最简单的方法是匹配那些链接的条件,将先前的结果通过管道传递到下一个表达式中。然后,如果任何匹配失败,则整个表达式失败:
$echo "tEsTstr1ng" | egrep "^.{8,255}"| egrep "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"| egrep "[abcdefghijklmnopqrstuvwxyz"] | egrep "[0-9]"
我手动输入了所有字符而不是“[AZ]”和“[az]”,因为不同的系统语言环境可能会将它们替换为 [aAbBcC...,这是一个匹配中的两个条件,我们需要检查 两个条件。
作为shell脚本:
#!/bin/sh
a="tEsTstr1ng"
b=`echo $a | egrep "^.{8,255}" | \
egrep "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]" | \
egrep "[abcdefghijklmnopqrstuvwxyz"] | \
egrep "[0-9]"`
# now featuring W in the alphabet string
#if the result string is empty, one of the conditions has failed
if [ -z $b ]
then
echo "Conditions do not match"
else
echo "Conditions match"
fi
【讨论】:
如果您的 grep 版本具有 -P 选项,则它支持 PCRE(Perl 兼容正则表达式。
grep -P '(?=^.{8,255}$)(?=^[^\s]*$)(?=.*\d)(?=.*[A-Z])(?=.*[a-z])'
我不得不更改您的表达式以拒绝空格,因为它总是失败。额外的一组括号似乎没有必要。我在最后省略了^.*,因为它总是匹配的,你真的只需要这样的布尔结果:
while ! echo "$password" | grep -P ...
do
read -r -s -p "Please enter a password: " password
done
【讨论】: