PostgreSQL扩展中Regex匹配异常:预期匹配却始终返回false
问题解决
你的代码存在两个关键错误,导致正则匹配始终返回false:
1. 正则表达式转义错误
在C语言字符串中,反斜杠\需要双重转义为\\,才能被正确传递给正则引擎。原代码中的\d{4}会被C编译器视为无效转义序列,实际传入正则引擎的模式丢失了匹配数字的规则,自然无法识别年份部分的数字。
2. 匹配字符串长度错误
测试字符串"Jan-2080"的实际字符长度是8(依次为J、a、n、-、2、0、8、0),但你传入RE_compile_and_execute的长度参数是9,这会让正则引擎读取超出字符串范围的内存,引发未定义行为,直接干扰匹配结果。
修正后的代码
PG_FUNCTION_INFO_V1(test_regex); Datum test_regex() { // 修复转义:\d 改为 \\d const char* mon_yyyy = "(?i)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec).*-.*\\d{4}"; text* mon_yyyy_text = cstring_to_text(mon_yyyy); char* data = "Jan-2080"; PG_RETURN_BOOL( RE_compile_and_execute( mon_yyyy_text, data, 8, // 修正为实际字符串长度8 0, (Oid)100, 0, NULL ) ); }
额外优化建议
- 不区分大小写的规则可以通过
RE_compile_and_execute的第四个参数(flags)传入RE_FLAGS_CASE_INSENSITIVE(需包含头文件regexp.h),这样可以去掉模式中的(?i),代码更清晰:// 去掉模式中的(?i),修改flags参数 const char* mon_yyyy = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec).*-.*\\d{4}"; // ... RE_compile_and_execute( mon_yyyy_text, data, 8, RE_FLAGS_CASE_INSENSITIVE, // 使用flags指定不区分大小写 (Oid)100, 0, NULL ) - 确保代码包含必要的头文件:
#include "postgres.h"、#include "fmgr.h"、#include "regexp.h",否则会出现编译错误。
内容的提问来源于stack exchange,提问作者anteater
相关产品推荐
相关产品推荐

