case "$1" in
all)
echo "$1"
;;
[a-z][a-z][a-z][a-z][a-z][a-z])
echo "$1"
;;
*)
printf 'Invalid: %s\n' "$3"
exit 1
;;
esac
在此情况下,唯一接受的输入是全部 6 个字符。它不接受 4 个字符或超过 6 个字符。
我在这里想做的是只允许字符,而不是数字或符号,但长度不受限制。
正确的语法是什么?谢谢
答案1
数字或者符号是字符。看起来您想要:
- 仅限字母字符 (
[[:alpha:]]
) - 或可能是字母字符,但仅限拉丁文字(如您的
a-z
建议) - 或者可能是拉丁字母中的字母字符,并且没有变音符号。
除非语言环境是 C/POSIX,否则[a-z]
匹配或多或少是随机的bash
(至少在 GNU 系统上)。
对于 1,您需要:
die() {
printf >&2 '%s\n' "$1"
exit 1
}
case $string in
("") die "Can't be empty";;
(*[![:alpha:]]*) die "contains non-alphabetical characters";;
(*) echo OK
esac
这将接受all
, Stéphane
(拉丁字母)、γράμμα
(希腊字母)、письмо
(西里尔字母),但不接受foo-bar
, 123
...
2 可能很棘手,特别是当您想考虑组合变音符号时。
对于 3,为了让它在任何区域设置中运行,您需要指定所需的字符:
ok=abcdefghijklmnopqstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
并在case
声明中使用
(*[!$ok]*) die "contains characters not allowed";;
或者您可以切换到基于字符代码点zsh
的范围,因此始终仅包含 abcdefghijklmnopqstuvwxyz 或使用 bash 4.3 或更高版本[a-zA-Z]
使用该globasciiranges
选项具有相同的行为bash
。
答案2
您可以使用标准模式匹配来执行此操作,方法是查找任何不允许的字符,并在找到任何字符时拒绝输入。或者你可以使用扩展的全局( extglob
) 或正则表达式,并明确确保整个字符串由以下字符组成是允许。
#/bin/bash
shopt -s extglob globasciiranges
case "$1" in *([a-zA-Z])) echo "case ok" ;; esac
[[ "$1" = *([a-zA-Z]) ]] && echo " [[ ok"
[[ "$1" =~ ^[a-zA-Z]*$ ]] && echo "rege ok"
globasciiranges
阻止[a-z]
匹配重音字母,但正则表达式匹配不遵守它。使用正则表达式,您需要进行设置LC_COLLATE=C
以防止匹配它们。
所有这些都允许空字符串。为了防止这种情况,请将星号更改为加号 (*
至+
)。
答案3
如果您正在使用bash
或等效项,请在脚本顶部包含该行set -s extglob
以启用扩展通配(正则表达式的一种形式),然后在语句中将case
选择器设置为+([[:alpha:]])
,当然后面跟着语句本身)
所需的内容case
。
alpha
是几个之一字符类手册页中定义bash
。它包含您所在区域的所有字母字符(大写和小写)。