MCH*_*MCH 30 c++ regex unicode utf-8 c++11
这个问题是Do C++ 11正则表达式与UTF-8字符串一起使用的扩展吗?
#include <regex>
if (std::regex_match ("?", std::regex("?") )) // "\u4e2d" also works
std::cout << "matched\n";
Run Code Online (Sandbox Code Playgroud)
该程序在Mac Mountain Lion上编译,clang++
具有以下选项:
clang++ -std=c++0x -stdlib=libc++
Run Code Online (Sandbox Code Playgroud)
上面的代码有效.这是一个标准范围正则表达式,"[?-?????]"
用于匹配任何日语汉字或汉字.它适用于Javascript和Ruby,但即使使用类似的版本,我似乎也无法使用C++ 11工作[\u4E00-\u9fa0]
.下面的代码与字符串不匹配.
if (std::regex_match ("?", std::regex("[?-?????]")))
std::cout << "range matched\n";
Run Code Online (Sandbox Code Playgroud)
改变语言环境也没有帮助.有任何想法吗?
所以我发现如果你添加+
到最后,所有范围都有效.在这种情况下[?-?????]+
,但如果你添加{1}
[?-?????]{1}
它不起作用.而且,它似乎超越了它的界限.它不会匹配拉丁字符,但它会匹配?
这是\u306f
和?
它\u3041
.他们都躺在下面\u4E00
nhahtdh还提出了regex_search,它也可以在不增加的情况下工作,+
但它仍然会遇到与上面相同的问题,因为它会超出其范围.同时也使用了语言环境.Mark Ransom建议它将UTF-8字符串视为一组愚蠢的字节,我认为这可能就是它所做的.
进一步推动UTF-8变得混乱的理论[a-z]{1}
和[a-z]+
匹配a
,但只[?-?????]+
匹配任何角色,而不是[?-?????]{1}
.
R. *_*des 34
以UTF-8编码,字符串"[?-?????]"
等于这一个:"[\xe4\xb8\x80-\xe9\xbe\xa0\xe3\x80\x85\xe3\x80\x86\xe3\x83\xb5\xe3\x83\xb6]"
.这不是您正在寻找的机器人角色类.
您正在寻找的角色类包括:
您指定的字符类包括:
凌乱不是吗?你看到了问题吗?
这与"拉丁"字符不匹配(我假设你的意思是像az这样的东西),因为在UTF-8中,所有字符都使用低于0x80的单个字节,而这些字符都不在那个混乱的字符类中.
它也不匹配"?"
因为"?"
有三个"字符",而你的正则表达式只匹配那个奇怪的长列表中的一个"字符".试试assert(std::regex_match("?", std::regex("...")))
,你会看到.
如果你添加+
它是有效的,因为"?"
在你奇怪的长列表中有三个"字符",现在你的正则表达式匹配一个或多个.
如果你改为添加{1}
它不匹配,因为我们回到匹配三个"字符"对一个.
顺便说一下"?"
比赛"?"
,因为我们以同样的顺序匹配三个"人物"对相同的三个"角色".
正则表达式+
实际上会匹配一些不需要的东西,因为它不关心顺序.可以从UTF-8中的字节列表中生成的任何字符都匹配.它将匹配"\xe3\x81\x81"
(ぁU + 3041),它甚至会匹配无效的UTF-8输入"\xe3\xe3\xe3\xe3"
.
更大的问题是你正在使用一个甚至没有1级支持Unicode的正则表达式库,这是最低要求.它会消耗大量的字节,而且你的珍贵的小正则表达式对它没有多大帮助.
更大的问题是你使用一组硬编码的字符来指定"任何日文汉字或汉字".为什么不使用Unicode Script属性呢?
R"(\p{Script=Han})"
哦,对,这不适用于C++ 11正则表达式.在那里,我几乎忘记了那些比使用Unicode无用的烦人.
那你该怎么办?
您可以将输入解码为a std::u32string
并char32_t
全部用于匹配.这不会给你这个烂摊子,但当你的意思是"一组共享某个属性的字符"时,你仍然会硬编码范围和异常.
我建议你忘记C++ 11正则表达式并使用一些具有最低1级Unicode支持的正则表达式库,就像ICU中那样.