C++ 如何使std::regex与Utf8匹配
我想要一个像“.c”这样的模式,使用std::regex将“.”与任何后跟“c”的utf8匹配 我在微软C++和g++下尝试过。我得到相同的结果,每次“.”只匹配一个字节 下面是我的测试用例:C++ 如何使std::regex与Utf8匹配,c++,regex,utf-8,C++,Regex,Utf 8,我想要一个像“.c”这样的模式,使用std::regex将“.”与任何后跟“c”的utf8匹配 我在微软C++和g++下尝试过。我得到相同的结果,每次“.”只匹配一个字节 下面是我的测试用例: #include <stdio.h> #include <iostream> #include <string> #include <regex> using namespace std; int main(int argc, char** argv)
#include <stdio.h>
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main(int argc, char** argv)
{
// make a string with 3 UTF8 characters
const unsigned char p[] = { 'a', 0xC2, 0x80, 'c', 0 };
string tobesearched((char*)p);
// want to match the UTF8 character before c
string pattern(".c");
regex re(pattern);
std::smatch match;
bool r = std::regex_search(tobesearched, match, re);
if (r)
{
// m.size() will be bytes, and we expect 3
// expect 0xC2, 0x80, 'c'
string m = match[0];
cout << "match length " << m.size() << endl;
// but we only get 2, we get the 0x80 and the 'c'.
// so it's matching on single bytes and not utf8
// code here is just to dump out the byte values.
for (int i = 0; i < m.size(); ++i)
{
int c = m[i] & 0xff;
printf("%02X ", c);
}
printf("\n");
}
else
cout << "not matched\n";
return 0;
}
#包括 #包括 #包括 #包括 使用名称空间std; int main(int argc,字符**argv) { //生成一个包含3个UTF8字符的字符串 常量无符号字符p[]={a',0xC2,0x80',c',0}; 要搜索的字符串((char*)p); //要匹配c之前的UTF8字符吗 字符串模式(“.c”); 正则表达式re(模式); std::smatch匹配; bool r=std::regex_搜索(搜索、匹配、重搜索); if(r) { //m.size()将是字节,我们预期为3 //预期为0xC2,0x80,'c' 字符串m=匹配[0];
不支持UTF8,我确实有另一个ReXEP库,但是我期待标准的支持。标准中的Unicode支持是不存在的。也许我误解了你的意思。正在查找?当您说UTF-8字符时,您的意思是“任何有效的UTF-8字符”,即包括ASCII表(0-127)或者您的意思是ASCII表之外的字符?如果字符长度仅为1字节,是否不希望进行匹配?如果是,则需要基于非正则表达式的方法。UTF-8很容易解释。如果第一位为0,则长度为1字节。如果不是,则多字节字符中的单个字节,并且您知道前面的字符大于127。如果要确保编码正确,只需从前导字节开始计算字节。感谢更新。我希望点“.”匹配任何字符,包括单字节和多字节。然后我将结果字符串匹配解释为utf8。看起来
cout一些正则表达式支持将匹配单个unicode字符的,该字符可能由许多字节组成,具体取决于编码方式。正则表达式引擎通常在引擎设计的编码中获取主题字符串的字节,因此您不必担心实际的编码g(无论是US-ASCII、UTF-8、UTF-16还是UTF-32) 另一个选项是\X
,其中FFFF指的是unicode字符集中该索引处的unicode字符。使用该选项,您可以在字符类内创建范围匹配,即\uFFFF
。同样,这取决于regex风格支持什么。在[\u0000-\uFFFF]
除了必须在大括号内提供unicode字符索引外,它也做同样的事情,并且不需要填充,例如\x{…}中还有另一个
的变体\u
编辑:该网站非常适合了解各种口味的regex 编辑2:要匹配任何Unicode独占字符,即不包括ASCII表中的字符/1字节字符,您可以尝试\x{65}
即,值为128-4294967295的任何字符,从ASCII范围外的第一个字符到当前使用最多4字节表示的最后一个unicode字符集索引(最初为6,将来可能会更改) 通过单个字节的循环将更有效,不过:“[\x{80}-\x{FFFFFFFF}”
如果前导位为0,即如果其有符号值为 ,则为1字节字符表示。跳到下一个字节,然后重新开始-1
否则,如果前导位为11110,即如果其有符号值为 ,-17
n=4
否则,如果前导位为1110,即如果其有符号值为 ,-33
n=3
否则,如果前导位为110,即如果其有符号值为 ,-65
n=2
或者,检查下一个 字节是否以10开头,即对于每个字节,如果其具有有符号值n
,则为无效的UTF-8编码<-63
现在您知道前面的n个字节构成了一个unicode独占字符。因此,如果下一个字符是“c”,即 ,您可以说它匹配-==99
返回true
使用宽字符和UTF32(如果您的编译器只支持UTF16)在标准C++中没有解决方案。所以基本上是代码> STD::ReGEX不是这样工作的。这是一个遗憾。std::regex