验证字符串是否仅包含ASCII字符和数字

时间:2013-05-24 09:15:41

标签: regex bash

我这样做是为了验证用户名:

if [[ "$username" =~ ^[a-z][_a-z0-9]{2,17}$ ]]; then

但实际上,接受包含é,ç,à等的unicode字符的用户名。 我应该使用什么正则表达式类将字符串限制为ascii字母(a,b,c,d ... z)?

4 个答案:

答案 0 :(得分:3)

您应该可以先设置LC_ALL=C(可能是暂时的,以免影响其他任何内容)。更现代的正则表达式引擎允许区域设置,它可以将重音字符折叠到它们的基本字符上(或者至少对它们进行排序,使它们介于az之间。

由于C语言环境只知道ASCII,这应解决问题。

例如,请参阅以下脚本:

#!/bin/bash

username=amélie_314159

for locale in '' 'C' ; do
    export LC_ALL="${locale}"
    printf "LC_ALL set to %-3s: '%s' is " "'$LC_ALL'" "${username}"
    if [[ "${username}" =~ ^[a-z][_a-z0-9]{2,17}$ ]] ; then
        echo valid
    else
        echo invalid
    fi
done

输出:

LC_ALL set to '' : 'amélie_314159' is valid
LC_ALL set to 'C': 'amélie_314159' is invalid

答案 1 :(得分:2)

bullet-proof 方式是将[a-z]简单地拼写为[abcdefghijklmnopqrstuvwxyz]。那里!自1970年1月1日00:00:00以来,没有搞乱语言环境或有趣的角色类,并且支持任何shell。面向未来,无论您的操作系统供应商,外壳供应商,Unix标准化流程或BOFH认为什么都很酷。

使用额外的变量lc,如

lc=abcdefghijklmnopqrstuvwxyz

正则表达式甚至变得可读:

[$lc][_0-9$lc]{2,17}

这是非常强大且可移植的configure脚本。

答案 2 :(得分:0)

使用以下内容:

if [[ "$username" =~ ^[\x00-\x7f]{2,17}$ ]]; then

答案 3 :(得分:0)

在使用正则表达式检查用户名是否具有正确长度等之前,您应该清理输入字符串。这意味着不应将不允许的内容列入黑名单,而应将实际允许的内容列入白名单。在这种情况下,我们将使用例如tr在实际正则表达式之前预先删除所有不需要的字符。当正则表达式检查后,它变得更加简单。

echo "abc[日本語][ひらがな][カタカナ][äüéçà]abc" | tr -dc "a-zA-Z"

这只会留下abcabc作为余数。