如何使 std::正则表达式匹配 Utf8
How to make std::regex match Utf8
>我想要一个像".c"这样的模式,使用std::regex将"."与任何utf8后跟"c"匹配。
我已经尝试过Microsoft C++和 g++。每次"."只匹配一个字节时,我都会得到相同的结果。
这是我的测试用例:
#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 matchedn";
return 0;
}
我希望模式".c"匹配我的tobesearched
字符串的 3 个字节,其中前两个是 2 字节 utf8 字符,后跟"c"。
某些正则表达式风格支持与单个 unicode 字符匹配的X
,该字符可能包含多个字节,具体取决于编码。正则表达式引擎通常以引擎设计使用的编码获取主题字符串的字节,因此您不必担心实际编码(无论是 US-ASCII、UTF-8、UTF-16 还是 UTF-32(。
另一个选项是 FFFF 引用 unicode 字符集中该索引处的 unicode 字符的uFFFF
。有了它,您可以在角色类中创建远程匹配,即[u0000-uFFFF]
.同样,这取决于正则表达式风格支持什么。x{...}
中还有另一种u
变体,它做同样的事情,除了 unicode 字符索引必须在大括号内提供,并且不需要填充,例如x{65}
.
编辑:这个网站非常棒,可以了解更多关于各种口味的正则表达式 https://www.regular-expressions.info
编辑 2:要匹配任何 Unicode 专用字符,即排除 ASCII 表中的字符/1 字节字符,您可以尝试"[x{80}-x{FFFFFFFF}]"
即任何值为 128-4,294,967,295 的字符,该字符从 ASCII 范围之外的第一个字符到当前最多使用 4 字节表示的最后一个 unicode 字符集索引(最初为 6, 并且将来可能会更改(。
不过,循环遍历单个字节会更有效:
- 如果引导位为0,即如果其有符号值为
> -1
,则为1字节字符表示。跳到下一个字节,然后重新开始。 - 否则,如果引线位为 11110,即如果其有符号值为
> -17
, 则n=4
. - 否则,如果引线位为 1110,即如果其有符号值为
> -33
,则n=3
。 - 否则,如果引线位为 110,即如果其有符号值为
> -65
,则n=2
。 - 或者,检查接下来的
n
个字节是否以 10 开头,即对于每个字节,如果它有一个有符号值< -63
,则它是无效的 UTF-8 编码。 - 您现在知道前面的 n 个字节构成了 unicode 独占字符。因此,如果下一个字符是"c",即
== 99
,你可以说它匹配 -return true
.
- 使用正则表达式regex_search在字符串中查找字符串
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- C++正则表达式无限循环
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 定义有趣的宏和正则表达式在Z3 C++绑定
- 带有多个字符分隔符的正则表达式
- C++ 使用增强正则表达式库时断言崩溃
- 有人可以帮助我处理正则表达式吗?
- 使用正则表达式获取大括号块的列表
- 正则表达式以匹配数字的重复模式,后跟任何类型的分隔符?
- 组合正则表达式部分使用 | 不起作用的 C++
- 为什么C++正则表达式这么慢?
- 如何使HTML5电子邮件验证正则表达式在C++中工作?
- 在C++中实现正则表达式
- C++正则表达式替换整个单词
- 用C++编写正则表达式的正确方法是什么?
- 如何从Stroustrup的C++书中解释这个正则表达式?
- 为什么这个正则表达式C++在括号表达式中抛出无效范围异常?
- C++:匹配正则表达式,什么是匹配?
- 如何使 std::正则表达式匹配 Utf8