老林的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语言新课, 想快速入门点此