【发布时间】:2019-03-05 07:45:33
【问题描述】:
出于某种原因,我不知道为什么,可能是我的系统或大脑中有些地方不太对劲,正则表达式“[AZ]”似乎无法识别字母“W”和“ [az]" 似乎无法识别字母“w”。示例:
for x in A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Y y Z z; do echo $x | egrep "[A-Za-z]"; done
我的输出是: 一种 一种 乙 b C C D d 乙 e F F G G H H 一世 一世 Ĵ j ķ ķ 大号 l 米 米 ñ n ○ ○ 磷 p 问 q R r 小号 s 吨 吨 ü 你 五 v X X 是 是的 Z z
如您所见,字母“W”和“w”都不见了。我是唯一一个?什么可能导致这种情况?如果是错误,我在哪里报告?这发生在 bash 和 zsh 中,它发生在 sed 和 egrep 中(可能更多,我只测试了这两个),所以问题似乎与一般的正则表达式有关......:o 那么……这是怎么回事??
- Manjaro 17.1.12
- XFCE 4.12
- bash 4.4.23(1)-release (x86_64-unknown-linux-gnu)
- zsh 5.5.1 (x86_64-unknown-linux-gnu)
- egrep 3.1
- sed 4.5
编辑:有人问我的语言环境,所以在这里。
$ locale
LANG=sv_SE.utf8
LC_CTYPE="sv_SE.utf8"
LC_NUMERIC=sv_SE.UTF-8
LC_TIME=sv_SE.UTF-8
LC_COLLATE="sv_SE.utf8"
LC_MONETARY=sv_SE.UTF-8
LC_MESSAGES="sv_SE.utf8"
LC_PAPER=sv_SE.UTF-8
LC_NAME=sv_SE.UTF-8
LC_ADDRESS=sv_SE.UTF-8
LC_TELEPHONE=sv_SE.UTF-8
LC_MEASUREMENT=sv_SE.UTF-8
LC_IDENTIFICATION=sv_SE.UTF-8
LC_ALL=
如果这是问题所在,那么我猜任何决定 sv_SE.UTF-8 是什么的东西都是错误的,因为字母“w”在 2006 年被添加到瑞典字母表中。 此外,如果 A-Z 间隔取决于当前语言环境,那么当语言环境设置为瑞典语时,[A-Ö] 是否应该适用于整个瑞典语字母表?它没有,它给出了一个错误信息。但是 [[:alpha:]] 似乎包括所有瑞典字母,所以我想我对此很满意。
【问题讨论】:
-
您的语言环境是什么?这不是由 shell 完成的,而是由平台的标准 C 库完成的。无论如何,字符排序顺序和类别区域设置运行时配置(
LC_CTYPE、LC_COLLATE和其他变量,如可以覆盖这些的LC_ALL)与调试相关(不,必要)。 -
...如果您使用的系统配置的语言不包括
W在其字母表中,那么您就是。请将locale命令的输出编辑成您的问题。 -
顺便说一句,
[A-Za-z]无论如何都是不好的形式(并且建议您使用它的“教学资源”不应该被信任);使用[[:upper:]]代替[A-Z]和[[:lower:]]代替[a-z],或[[:alpha:]]用于两者,否则使用AaBb...Zz代替A..Za..z的排序规则会搞砸你。 -
(因为这都是标准 C 库功能,它更像是一个通用的 UNIX 问题,而不是一个专门关于
sed或grep或诸如此类的问题;它们都调用相同的共享库代码正则表达式或 fnmatch 模式/glob 支持)。 -
@Charles:确实 [[:alpha:]] 通常比 [A-Za-z] 更好,值得指出这一点。但是,我们不要忘记 glibc 中存在错误的事实,这里。正则表达式
[u-x]应该匹配v和w,即使是瑞典语也是如此。但事实并非如此。但是,w确实排序正确,并且确实以正确的 ctype 显示。