老林的C语言新课, 想快速入门点此
@[TOC](C语言正则表达式库 pcre2 简述(chitGPT给出的回答和我的补充))
前言
PCRE2(Perl Compatible Regular Expression 2)是一个支持 Perl 语法的正则表达式库。它是 PCRE(Perl Compatible Regular Expression)的升级版,提供了更多的功能和更高的性能。
PCRE2 可以用于 C、C++、Java、Python、PHP 等多种编程语言中,用于处理文本匹配、搜索和替换等操作。
一、pcre2的使用 ( 以下AI给的代码有误, 不要抄, 看最后 )
使用 PCRE2,需要先安装库文件和头文件。然后在代码中包含头文件,调用相应的函数进行正则表达式的操作。例如,以下是一个 C++ 中使用 PCRE2 进行正则表达式匹配的示例:
#include #include int main(){// 定义正则表达式PCRE2_SPTR pattern = (PCRE2_SPTR) "hello (world)";// 定义输入字符串PCRE2_SPTR input = (PCRE2_SPTR) "hello world, hello PCRE2!";// 编译正则表达式pcre2_code *re;int errorcode;PCRE2_SIZE erroroffset;re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &errorcode, &erroroffset, NULL);// 匹配正则表达式pcre2_match_data *match_data;match_data = pcre2_match_data_create_from_pattern(re, NULL);int rc;rc = pcre2_match(re, input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);// 输出匹配结果if (rc > 0){PCRE2_SPTR substring_start;PCRE2_SIZE substring_length;substring_start =pcre2_get_substring(input, match_data, 1, &substring_length);std::cout << "Match: ";std::cout.write((char *)substring_start, substring_length);std::cout << std::endl;pcre2_substring_free(substring_start);}// 释放内存pcre2_match_data_free(match_data);pcre2_code_free(re);return 0;}
以上代码定义了一个正则表达式 hello (world),表示匹配字符串中的 hello world。然后编译正则表达式,使用 pcre2_match 函数进行匹配,如果成功则输出匹配结果。
PCRE2 还提供了许多其他的函数和选项,可以根据需要进行使用。
二、使用pcre2匹配中文 ( 以下AI给的代码有误, 不要抄, 看最后 )
要在 PCRE2 中匹配中文,您需要考虑以下几点:
中文的编码方式:中文通常使用 UTF-8 编码,所以您需要确保在 PCRE2 中使用 UTF-8 编码。
使用 Unicode 属性:PCRE2 提供了 Unicode 属性,可以识别不同的字符类别,包括中文字符。
以下是一个使用 PCRE2 匹配中文的示例代码:
#include #include int main(){const char *pattern = "\\p{Han}+"; // 匹配中文字符const char *subject = "你好,世界!Hello, world!";PCRE2_SPTR pattern_utf8 = (PCRE2_SPTR)pattern;PCRE2_SPTR subject_utf8 = (PCRE2_SPTR)subject;int errorcode, rc;PCRE2_SIZE erroroffset;pcre2_code *re;pcre2_match_data *match_data;// 编译正则表达式re = pcre2_compile(pattern_utf8, PCRE2_ZERO_TERMINATED, 0, &errorcode, &erroroffset, NULL);if (re == NULL){printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset, pcre2_get_error_message(errorcode));return 1;}// 准备匹配数据match_data = pcre2_match_data_create_from_pattern(re, NULL);// 执行匹配rc = pcre2_match(re, subject_utf8, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);if (rc < 0){printf("PCRE2 matching failed: %d\n", rc);return 1;}// 输出匹配结果printf("Matched %d characters:\n", rc);PCRE2_SPTR match_str = subject_utf8 + pcre2_get_startchar(match_data);for (int i = 0; i < rc; i++){printf("%c", (char)match_str[i]);}printf("\n");// 释放资源pcre2_match_data_free(match_data);pcre2_code_free(re);return 0;}
该示例使用 \p{Han}+ 正则表达式匹配中文字符,输出结果为:
Matched 6 characters:你好世界
注意,由于中英文字符混合,输出结果可能不是您期望的。如果您只想匹配中文字符,可以将正则表达式修改为 \p{Han}+。
总结
上面是CSDN的AI模型chitGPT做的有关pcre2正常表达式库的简要介绍, 我先验证一下, 看看代码有没有什么问题.
很遗憾, 上面两个代码都有相当错误, 需要修改, 修改后的代码见下面
编译参数:需要引入8位和16位的库(不冲突)
E:\msys64\clang64\bin\clang.exe -glldb -lpcre2-16 -lpcre2-8 test196_8*.c -o E:\clangC++\answer\C\test196_8.exe
第一个程序:
#define PCRE2_CODE_UNIT_WIDTH 8#include #include int main(){// 定义正则表达式PCRE2_SPTR pattern = (PCRE2_SPTR) "hell(\\w)"; // (world)";// 定义输入字符串PCRE2_SPTR input = (PCRE2_SPTR) "hellp hello world,PCRE2!";// 编译正则表达式pcre2_code *re;int errorcode;PCRE2_SIZE erroroffset;re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &errorcode, &erroroffset, NULL);// 匹配正则表达式pcre2_match_data *match_data =pcre2_match_data_create_from_pattern(re, NULL);int rc =pcre2_match(re, input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);// 输出匹配结果while (rc > 0){printf("Match: \n");PCRE2_SPTR substring_start;PCRE2_SIZE substring_length;for (int i = 0; i < rc; i++){substring_start = input + ovector[2 * i];substring_length = ovector[2 * i + 1] - ovector[2 * i];printf("%2d: %.*s\n", i, (int)substring_length, (char *)substring_start);}input = substring_start + substring_length;rc = pcre2_match(re, input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);ovector = pcre2_get_ovector_pointer(match_data);}// 释放内存pcre2_match_data_free(match_data);pcre2_code_free(re);return 0;}
第二个程序:
#define PCRE2_CODE_UNIT_WIDTH 16#include #include #include int main(){setlocale(LC_CTYPE, "");PCRE2_SPTR16 pattern_utf16 =(PCRE2_SPTR16)L"(\\p{Han})+"; // 匹配中文字符pattern;PCRE2_SPTR16 subject_utf16 =(PCRE2_SPTR16)L"Hello, world! 你好,世界!"; // subject;int errorcode;int rc;size_t erroroffset;pcre2_code_16 *re;pcre2_match_data_16 *match_data;// 编译正则表达式re = pcre2_compile_16(pattern_utf16, PCRE2_ZERO_TERMINATED, 0, &errorcode,&erroroffset, NULL);if (re == NULL){PCRE2_UCHAR16 buffer[256];pcre2_get_error_message_16(errorcode, buffer, sizeof(buffer));wprintf(L"PCRE2 compilation failed at offset %d: %s\n",(int)erroroffset, buffer);return 1;}// 准备匹配数据match_data = pcre2_match_data_create_from_pattern_16(re, NULL);// 执行匹配rc = pcre2_match_16(re, subject_utf16, PCRE2_ZERO_TERMINATED, 0, 0,match_data, NULL);if (rc < 0){printf("PCRE2 matching failed: %d\n", rc);return 1;}// 输出匹配结果printf("Matched %d characters:\n", rc);PCRE2_SPTR16 match_str = subject_utf16 + pcre2_get_startchar_16(match_data);for (int i = 0; i < rc; i++){wprintf(L"%c", (wchar_t)match_str[i]);}printf("\n");// 释放资源pcre2_match_data_free_16(match_data);pcre2_code_free_16(re);return 0;}
貌似AI对于这个正则库的api并不熟悉, 而且还会自造函数, 这确实令人苦恼, 关键是我想通过AI快速掌握这个库, 结果还是需要看文档.
以下是文档中核心函数的最简要解说.
此正则库有三种编码, 8,16,32位, 对于普通ASCII码, 8位即可, 中文需要16位(Windows环境)
#define PCRE2_CODE_UNIT_WIDTH 16
为了用中文, 需要给出区域头文件, 加上库文件
#include #include
设置中文环境
const char *loc = setlocale(LC_CTYPE, "");
用宽字符声明模式字符串
PCRE2_SPTR16 pattern = (PCRE2_SPTR16)L"\\p{Han}+"; // 匹配中文字符pattern;
声明匹配字符串
PCRE2_SPTR16 subject =(PCRE2_SPTR16)L"Hello, world! 你好,世界!"; // subject;
编译正则表达式
int errorcode;size_t erroroffset;// 编译正则表达式pcre2_code_16 *re = pcre2_compile_16(pattern, // 模式字符串PCRE2_ZERO_TERMINATED, // 字符长度0, // 默认选项&errornumber,// 错误号&erroroffset,// 错误偏移NULL); // 一般用NULL
如果编译返回NULL, 输出错误结束程序
if (re == NULL){PCRE2_UCHAR16 buffer[256];pcre2_get_error_message_16(errorcode, buffer, sizeof(buffer));wprintf(L"PCRE2 compilation failed at offset %d: %s\n",(int)erroroffset, buffer);return 1;}
声明一个匹配数据, 用于存放匹配结果
// 准备匹配数据pcre2_match_data_16 *match_data =pcre2_match_data_create_from_pattern_16(re, NULL);
执行匹配
size_t offset = 0;// 匹配成功的数量int rc = pcre2_match_16(re, // 正则表达式subject, // 待匹配字符串PCRE2_ZERO_TERMINATED, // 字符串长度offset, // 开始匹配时的偏移量0,// 默认选项match_data, // 匹配数据存放地址NULL// 默认为NULL);if (rc < 0){printf("PCRE2 matching failed: %d\n", rc);return 1;}
获取匹配数组, 匹配位置偏移量存储在此数组中
size_t *ovector = pcre2_get_ovector_pointer_16(match_data);
输出匹配结果
while (rc > 0){printf("Match: \n");for (int i = 0; i < rc; i++){wprintf(L"%2d: %.*s\n", i,(int)(ovector[2 * i + 1] - ovector[2 * i]),// 匹配的开始和结束位置在ovector数组中, 求差得出匹配字符个数 (wchar_t *)(subject + ovector[2 * i]));// 通过偏移到达匹配位置, 从匹配的第一个字符开始打印}offset = ovector[2 * (rc - 1) + 1];// 设置本次匹配字符结尾的偏移量, 做下一次匹配的开始位置rc = pcre2_match_16(re, subject, PCRE2_ZERO_TERMINATED, offset,// 从上次匹配的末尾开始匹配 0,match_data, NULL);ovector = pcre2_get_ovector_pointer_16(match_data);// 获取匹配结果数组}
将正则表达式和匹配数据资源回收
// 释放资源pcre2_match_data_free_16(match_data);pcre2_code_free_16(re);
以上就是正则库的简述, 目前还是自己看文档, AI还暂时不能解决这种问题.
老林的C语言新课, 想快速入门点此