使用正则表达式限制字符数

时间:2019-01-31 10:46:06

标签: regex bash shell

我有以下read,它将采用first.last形式的用户名。这由下面的正则表达式处理。如何将最大字符数限制为16

我曾尝试添加^[a-zA-Z]+\.[a-zA-Z]+{,16}$,但是在测试时,允许我创建密码> 16个字符

read -p "Enter a Username (firstname.lastname): " username
until [[ "${username}" =~ ^[a-zA-Z]+\.[a-zA-Z]+$ ]];
do
        read -p "Incorrect format, retry Username: " username
done

结果是,用户名read最多只能使用16个字符。

修改

我设法按原本希望的方式使用了非正则表达式解决方案,

read -p "Enter a Username (first.last): " username

until [[ "${username}" =~ ^[a-zA-Z]+\.[a-zA-Z]+$ ]] && (( 
"${#username}" < 16 )); do
    read -p "Maximum of 16 characters, try again: " username
done

输出:

好:

bash -x userInt.sh
+ read -p 'Enter a Username (first.last): ' username
Enter a Username (first.last): foo.bar
+ [[ foo.bar =~ ^[a-zA-Z]+\.[a-zA-Z]+$ ]]
+ ((  7 < 16  ))
+ read -sp 'Enter a Password (Minimum 8 characters): ' password

错误:

bash -x userInt.sh
+ read -p 'Enter a Username (first.last): ' username
Enter a Username (first.last): someones.reallylongname
+ [[ someones.reallylongname =~ ^[a-zA-Z]+\.[a-zA-Z]+$ ]]
+ ((  23 < 16  ))
+ read -p 'Maximum of 16 characters, try again: ' username

2 个答案:

答案 0 :(得分:1)

您没写你的,如果16个字符应该是双方还是各姓氏或名字的限制。

如果您希望每16个字符有一个限制,可以按照以下方式进行操作:

^[a-zA-Z]{1,16}\.[a-zA-Z]{1,16}$

如果它应该是一个整体的限制,那么你可以做这样的(不包括从计数点):

^[a-zA-Z]{1,8}\.[a-zA-Z]{1,8}$

首次修改: 我没有包括bash代码(根据您的问题):

read -p "Enter a first name (firstname.lastname): " username
until [[ "${username}" =~ ^[a-zA-Z]{1,8}\.[a-zA-Z]{1,8}$ ]];
do
        read -p "Incorrect format, retry Username: " username;
done

这将对名和姓都施加8个字符的限制。正如我在评论建议你应该做一个姓/名长度统计,并据此调整它的极限。

答案 1 :(得分:1)

首先,如果您提供的所有信息都是“格式错误”,那么您的用户就会讨厌您。其次,您要问很多一个正则表达式。是的,您也许可以使用正则表达式来执行,但是有些遗憾的家伙将它维护在您身后。 :)

我假设您只是禁止使用所有非Alpha。您确定也不想自动将其转换为小写吗?顺便说一句,这将禁止扩展字符,并且firstname.lastname是一个非常以欧洲为中心的思维方式...

declare -l username # forces values to lowercase
msg="Please use only letters with a single dot separator, and limit the total to 16 characters."
while read -p "Enter a Username (firstname.lastname): " username
do case "$username" in                                # check for
   # too long  | invalid chars | multidots
   ?????????????????*|*[^a-z.]*|*.*.*) echo "$msg" ;; # add A-Z if not downcasing
   *.*) break;;                                       # this is the format we want
   *) echo "$msg" ;;                                  # a catch-all in case we missed anything else
   esac
done

正则表达式比通配符更强大,但这对我来说更易读。 YMMV。