我在 AIX 上使用 ksh,我想检查变量(例如var1=sanySAN
)var2=SANYsa%$3
是否是字母数字。
这里,var1
是字母数字,而var2
不是。我知道我可以使用[a-z][A-Z][0-9]
or[:alnum:]
但我不知道如何使用。
我应该这样检查吗?
if [[ var == [:alnum:]* ]]
then
echo "yes"
else
echo "no"
fi
我尝试了很多方法但都失败了。
答案1
正面:
is_alnum() {
case $1 in (*[![:alnum:]]*|"") false;; esac
}
然后:
$ is_alnum 123 && echo yes
yes
$ is_alnum % || echo no
no
mksh
是唯一一个使用上述方法失败的 shell。
另请注意,如果变量包含不形成有效字符的字节序列,则此方法将不起作用。
yash
仅适用于有效的 unicode 字符,因此它是唯一报告错误的:
$ is_alnum $'A\xe9B'
yash: cannot convert the argument `A�B' into a wide character stringyash: the argument is replaced with an empty string
更新
mksh
在 R56 中添加了字符类,并修复了R56c。
答案2
你可以做:
[[ $var = +([[:alnum:]]) ]]
这可以在 AT&T ksh 和zsh
的实现中工作ksh
,但显然不能在pdksh
基于 的实现中工作。这适用于zsh -o kshglob
(就像当zsh
被调用时ksh
)或bash -O extglob
一样。
+(...)
是ksh
通配符一个或多个。[[:alnum:]]
是当前区域设置中被视为字母数字的任何字符(任何字母表中,不一定只是拉丁字母表)。
如果您想限制为英文字母和数字,假设LC_ALL
未设置变量,您可以这样做:
LC_COLLATE=C; [[ $var = +([a-zA-Z0-9]) ]]
如果不:
[[ $var = +([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]) ]]
这:
LC_ALL=C; [[ $var = +([[:alnum:]]) ]]
即使它改变了字符的含义也应该起作用。因为包含与 ASCII 数字相对应的字节的字符(例如 GB18030 中的 £ 被编码为 81 30 84 35,其中 30 也恰好是 ASCII 0)也将包含非 ASCII 的字节(例如 81 84 £),并且给定系统上的所有字符集必须就可移植字符集中的字符编码达成一致,其中包括所有英文字母数字。
另请注意,在 UTF-8 语言环境中,ksh93u+(至少)当前存在一个错误,即如果$var
包含不形成有效字符的字节序列,但这些字节对应于 ISO-8859-1 字符集中的数字,则他们将被视为alnums
。例如,$'A\xe9B'
会被视为字母数字,因为 0xe9 在 ISO-8859-1 中是 é。 (U+00E9 是é
,但是 é 的 UTF-8 编码是 0xc3 0xa9,而不是 0xe9)。
答案3
一些想法基于expr
:
if expr "x$string" : '.*[^[:alnum:]]' >/dev/null;
then
printf "%s is NOT alphanumeric\n" "$string"
else
printf "%s is alphanumeric\n" "$string"
fi
请注意,使用printf
overecho
是有意为之,因为"$string"
是任意字符串。更多信息这里。此外,开头的“x”可防止扩展为以 开头的内容expr
时发生阻塞。感谢 Stéphane 和 Sato 通过他们的评论帮助完善此答案。$string
-
答案4
感谢您的所有帮助..经过多次尝试,我得到了这个解决方案。
var=`echo "some-value" | tr -d "[:alnum:]"`
if [ "$var" == "" ]; then
echo " string has only alphanumerics"
else
echo "something other than alphanumerals is there"
fi