人类会认为以下字符串表示相同的文本:
>>> [b'a\xc3\xa9b'.decode('utf-8'), b'ae\xcc\x81b'.decode('utf-8')]
['aéb', 'aéb']
一个字符串使用预组合字符,另一个使用分解字符,但生成的文本是相同的。
但是,ICU似乎不支持匹配预合成和分解的字符:
UParseError pe;
UErrorCode status;
URegularExpression *regexp = uregex_open(L"a\u0065\u0301b", 4, URegexpFlag::UREGEX_CASE_INSENSITIVE, &pe, &status);
uregex_setText(regexp, L"a\u00E9b", 3, &status);
UBool success = uregex_matches(regexp, 0, &status); // fails
uregex_close(regexp);
PCRE也没有:
$ LC_ALL=en_US.UTF-8 pcretest <(printf '%s\n' $'/ae\xcc\x81b/i' $'a\xc3\xa9b')
PCRE version 8.45 2021-06-15
/aéb/
aéb
No match
所以,如果我想处理任意正则表达式的这种情况(以便结果对人类有意义)......那么我该怎么做呢?
有没有一种方法可以让现有的库在任意Unicode正则表达式和语料库中正确工作?
是否存在任何正则表达式库可以完全处理Unicode(除了全大小写折叠等)?
理想情况下,我希望我可以在C++中使用的东西,但其他语言的解决方案也很受欢迎。
1条答案
按热度按时间5kgi1eie1#
如果你想比较两个字符串的等价性,而不管它们的标准化形式如何,ICU有
unorm_compare()
。例如:在编译和运行时,打印出