这个问题是关于C++11正则表达式是否适用于UTF-8字符串的扩展。
#include <regex>
if (std::regex_match ("中", std::regex("中") )) // "\u4e2d" also works
std::cout << "matched\n";
该程序在Mac Mountain Lion上使用clang++
编译,选项如下:
clang++ -std=c++0x -stdlib=libc++
以上的代码是有效的。这是一个用于匹配任何日语汉字或中文字符的标准范围正则表达式:"[一-龠々〆ヵヶ]"
。它适用于JavaScript和Ruby,但我似乎无法在C++11中使用类似版本的 [\u4E00-\u9fa0]
进行范围匹配。以下代码不匹配字符串。
if (std::regex_match ("中", std::regex("[一-龠々〆ヵヶ]")))
std::cout << "range matched\n";
更改语言环境也没有帮助。有什么想法吗?
编辑
所以我发现,如果在结尾添加+
,所有范围都有效。在这种情况下是[一-龠々〆ヵヶ]+
,但如果添加{1}
[一-龠々〆ヵヶ]{1}
则不起作用。此外,它似乎超出了边界。它不能匹配拉丁字符,但它会匹配は
(\u306f
)和ぁ
(\u3041
)。它们均位于\u4E00
以下。
nhahtdh还建议使用regex_search,它也可以在不添加+
的情况下工作,但它仍然遇到与上述相同的问题,即将值拉出其范围。还稍微调整了语言环境。Mark Ransom表示它将UTF-8字符串视为一组哑字节,我认为这可能就是它正在做的事情。
进一步推测UTF-8有些混乱,[a-z]{1}
和[a-z]+
匹配a
,但只有[一-龠々〆ヵヶ]+
匹配任何字符,而不是[一-龠々〆ヵヶ]{1}
。
std::locale::global(std::locale("ja_JP.UTF-8"));
和使用相同结果的imbue (std::locale("ja_JP.UTF-8"));
,就像我在编辑部分展示的那样。还尝试了 ja_JP、ja_JP.eucJP 和 ja_JP.SJIS。 - MCHstd::string
是一个 字节 字符串。为什么多字节字符可以工作?如果您想使用 Unicode 字符,请使用诸如 ogonek 的库。 - Konrad Rudolphstd::regex
只是分析底层代码单元,如果那些恰好是字节,那么它就处理字节。只要我们想要将某个东西视为一个单位的东西不超过一个字节,那就没问题了。 “到处使用UTF8”建议很好,但仅适用于字符串的透明存储(大多数情况下足够),当您从一个点检索字符串并将其传递给另一个点而不对其进行任何其他操作时。 - Konrad Rudolph