POSIX 中定义了一些“字符类”,如下所示LC_CTYPE 语言环境定义具有以下 (12) 个名称:
alnum alpha blank cntrl digit graph lower print punct space upper xdigit
并用作[[:lower:][:digit:]]
.
每个都被设置为定义一个非常精确的字符列表。
例如,digit
本应仅包含字符0123456789
。
然而,随着时间的推移和使用,a 的确切定义digit
一直在变化。 Perl 显然比0123456789
. Grep 还可以匹配多个0123456789
:
$ echo '0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९' |
grep -o '[0-9]\+'
0123456789
٠١٢٣٤٥٦٧٨
۰۱۲۳۴۵۶۷۸
߀߁߂߃߄߅߆߇߈
०१२३४५६७८
这通常是由于所使用的字符国际化的压力造成的。例如: 对于希腊国民来说,将αβγδεζηθικλμνξοπρσςτυφχψω
其视为降低大小写字母。但这并不是已定义的内容。事实上,所有这些“字符类”都添加了这个限制它的 POSIX 页面定义:
在 POSIX 语言环境中
这表明字符类仅在 C 语言环境中定义(且有效)。
这对于需要稳定且定义良好的字符列表的程序员来说最有用。
这[0-9]
只能意味着0123456789
对程序员来说似乎是合理的。
同样,an[a-z]
似乎只abcdefghijklmnopqrstuvwxyz
对程序员有意义。但如果[a-z]
读作“小写字母”,那么,对于希腊国民来说,不包含任何字母似乎是不合理的αβγδεζηθικλμνξοπρσςτυφχψω
。对于整理顺序(C 除外)的用户来说,这似乎不合理,但这[a-z]
并不意味着aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYz
.但反过来,这对于天真的用户来说可能是意想不到的。许多用户抱怨该范围[a-z]
包含大写字母。
简而言之:字符类仅为 C 语言环境定义。
其余区域设置尚未定义,这妨碍了它们的使用。无法要求希腊语中的小写字母。或者将它们包含在字符范围内。这在当今的计算机世界中是令人震惊的,因为当今的计算机世界可以轻松地在网页中使用所有语言。
现在,我们可以对此进行改进。
试图限制现在多样化的解释很可能会失败。我们需要一个新的语法。如果我们扩展字符类以准确地编写我们想要它们表示的含义会怎样:
Only digits from ASCII: [:as:digit:] <==> 0123456789
Only digits from English: [:en:digit:] <==> 0123456789
Only digits from Persian (Farsi): [:fa:digit:] <==> ۰۱۲۳۴۵۶۷۸۹
Only lowercase letters from English: [:en:lower:] <==> abcdefghijklmnopqrstuvwxyz
Only lowercase letters from Greek: [:el:lower:] <==> αβγδεζηθικλμνξοπρσςτυφχψω
Only uppercase from Russian: [:ru:upper:] <==> БВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
.
.
etc.
在任何/所有语言环境中稳定且相同(如果语言环境可以对字符进行编码)。
应该联系谁来在某些实用程序(也许是 grep、sed、bash)中实现这个想法?
答案1
该问题已在 POSIX 中使用宽字符函数得到解决。从...开始<wctype.h>
和<wchar.h>
,它与当前语言环境, 和<locale.h>
用于指定可能是哪个区域设置。
似乎没有人发现有必要添加特殊语法来在正则表达式中引用多个不相关的语言环境。
答案2
应该联系谁来在某些实用程序(也许是 grep、sed、bash)中实现这个想法?
已经有一定程度的支持,例如在使用 GNU C 库及其语言环境定义的系统上,“é”在法语语言环境中被识别为小写字母,“α”在希腊语语言环境中被识别为小写字母。波斯语,如 GNU C 库中所定义,使用 0123456789在某些情况下(尤其是scanf
带有printf
修饰符I
),但它们不属于“数字”类,我想 Sharif FarsiWeb 知道他们在这方面正在做什么。
如今提出此类更改的建议有点复杂。你随时可以加入奥斯汀集团并在那里讨论这个问题,或者通过邮件列表或者错误追踪器(理想情况下,首先在邮件列表中潜伏一段时间,或阅读档案);但 POSIX 并不是真正值得尝试的地方驾驶无需任何现有实现即可进行更改。您可以尝试向所涉及的各种工具的开发人员建议更改,大概从某些 C 库或其他库中的语言环境定义开始,但如果没有一些紧迫的情况(通常是标准要求),您不太可能走得太远,所以你最终会陷入第二十二条军规的境地。
如今,我认为最好的选择是为大型操作系统编辑器之一的重要客户提出一个有效的用例,并以这种方式推动变革。然后编辑将为您处理所有社区争论。