考虑以下命令:
STR="Êîðîëü è Øóò"; # Invalid (Russian in unrecognized encoding)
#STR="а б в г д"; # Valid (Russian)
#STR="a b c d e"; # Valid (English)
#STR="a b c d e а б в г д"; # Valid (English and Russian)
# The regex consists of latin and Russian characters
REGEX="^[a-zA-Zа-яА-Я ]+$"
if ! [[ "$STR" =~ $REGEX ]] ; then
echo "Unreadable string: ""$STR";
fi
$ echo $LC_ALL
ru_RU.UTF-8
我期望"Unreadable string: Êîðîëü è Øóò"
有输出,但什么也没有。
答案1
除了 POSIX 语言环境之外,POSIX 未指定likeA-Z
或match 的范围(对于,不明显)。а-я
A-Z
а-я
只有在 POSIX 语言环境中,您才能获得仅[A-Z]
匹配字符的保证。ABCDEFGHIJKLMNOPQRSTUVWXYZ
在其他区域设置中,行为因实现而异。有些可以匹配在之前A
和之后排序的任何整理元素(可以是字符或字符序列)Z
(可能包括ch
,x
或Á
,但不Ź
包括在内),或者它们可以匹配代码点大于A
且小于的字符语言环境的字符集中的字符集Z
,或者他们可以以不同的方式使用语言环境的排序规则数据...另请注意,并非每个人都同意任何给定脚本的字母顺序(例如在这种情况下为拉丁语或西里尔语),因此您对于在其字符集中包含这些脚本的不同区域设置(即使是相同的字符集),将会获得不同的行为。
如果您想匹配任何脚本中的任何字母字符,请使用[[:alpha:]]
,如果您想根据 UTF-8 中的代码点匹配字符范围,您可以尝试使用C.UTF-8
许多系统上可用的区域设置。
如果您想匹配拉丁文中的任何字母,您可以使用perl
or pcre
's \p{Latin}
(包括é
, Ê
...)。在zsh
:
set -o rematchpcre
[[ $x =~ '^(\p{Latin}|\p{Cyrillic})$' ]]
您可以将拉丁字母限制为仅在 ASCII 中找到的字母( still withzsh
和 still with rematchpcre
):
[[ $x =~ '^((?=[[:ascii:]])\p{Latin}|\p{Cyrillic})$' ]]
尽管在 , 中有效rematchpcre
,但^([a-zA-Z]|\p{Cyrillic})$
具有相同的效果,因为 PCRE 和 in 中的范围zsh
基于代码点值,并且这些字母保证具有相同的代码点,并且位于英语字母顺序中,所有语言环境均基于 ASCII 和基于 EBCDIC 的 POSIX至少系统。
或者,如果您只想要一个子集,则可以明确列出字符,以避免所有歧义:
[[ $x =~ ^[ABC...XYZabc...xyzабв...эюя]$ ]]
您始终可以将它们存储在变量中,例如:
ascii_upper=ABC...XYZ
ascii_lower=abc...xzy
cyr_upper=...
[[ $x =~ ^[$ascii_upper$ascii_lower$cyr_upper...]$ ]]