Collation order throughLC_COLLATE
不仅定义了单个字符的排序顺序,还定义了字符范围的含义。或者是吗?考虑以下片段:
unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'
Run Code Online (Sandbox Code Playgroud)
直观地说,B
不是 in [a-z]
,所以这不应该输出任何东西。这就是 Ubuntu 8.04 或 10.04 上发生的事情。但是在一些运行 Debian lenny 或挤压的机器上,B
可以找到,因为范围a-z
包括排序顺序之间a
和z
排序顺序中的所有内容,包括大写字母B
到Z
.
所有测试的系统都en_US
生成了语言环境。我还尝试改变语言环境:在B
上面匹配的机器上,{en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8}
除了日语(任何可用的编码)和C
/之外的每个可用语言环境(主要基于拉丁语:,还有中文语言环境)都会发生同样的情况POSIX
。
当您超越 ASCII 时,字符范围在正则表达式中意味着什么?为什么一方面某些 Debian 安装与其他 Debian 安装和 Ubuntu 之间存在差异?其他系统的行为如何?谁是对的,谁应该报告错误?
(请注意,我特别询问字符范围的行为,例如[a-z]
在en_US
语言环境中,主要是在基于 GNU libc 的系统上。我不是在询问如何匹配小写字母或 ASCII 小写字母。)
在两台 Debian 机器上,一台B
在[a-z]
,一台不在,输出LC_COLLATE=en_US …
可能的重复:
匹配包含 a-zA-Z 以外字符的单词
我不明白vim
一个词的定义。来自运动的帮助w
( :h w
):
w [count] 字数。|独家| 运动。这些命令在单词或 WORDS 上移动。
Run Code Online (Sandbox Code Playgroud)*word*
一个单词由一系列字母、数字和下划线或一系列其他非空白字符组成,以空格(空格、制表符、.)分隔。这可以通过 'iskeyword' 选项改变。
这意味着当我调用w
动作时,vim 需要检查哪些字符可以在iskeyword
选项的帮助下组成一个单词。因此,让我们检查一下,一个单词可能包含哪些字符:
:set iskeyword?
iskeyword=@,48-57,_,192-255
Run Code Online (Sandbox Code Playgroud)
让我们用iskeyword
选项中列出的字符中未包含的字符来测试一下,例如U+015B LATIN SMALL LETTER S
WITH ACUTE
. 按ga
on?
告诉我们它有十进制值 347,它大于 255,因此超出
iskeyword
. 光标放在t
tre?? 我按w
:
tre?? bar
^ (cursor)
Run Code Online (Sandbox Code Playgroud)
结果:
tre?? bar
^ (cursor)
Run Code Online (Sandbox Code Playgroud)
如果一个单词可以由字母、数字、下划线和其他字符组成,那么唯一的可能性就是 vim 将 the?
视为字母,因为它显然不是数字或下划线。让我们来看看如何判断一个字符是否是一个字母。来自:h
:alpha:
:
支持以下字符类: …