云数据库 PostgreSQL 高性能正则函数

PostgreSQL 内置的 POSIX 正则实现基于 NFA/ 回溯,遇到复杂模式或长字符串时容易触发指数级回溯(catastrophic backtracking),成为 CPU 热点。tencentdb_regex 扩展将 Google RE2 引擎(deterministic 自动机、有界最坏复杂度)打包进云数据库 PostgreSQL,提供与主干 regexp_* 语义对齐但性能更稳定的替代函数。

相关产品
云数据库 PostgreSQL 产品页,含版本规格、价格与购买入口。

一、前置条件

PostgreSQL 18,版本 ≥ v18.4_r1.10。

二、使用限制

·正则语法遵循 RE2 语法(PCRE 兼容子集,不支持反向引用 \\1 与部分 look-around)。若正则中依赖这些高级特性,请继续使用主干 regexp_*。

·tencentdb_regex 的 flags 语义与主干 regexp_* 一致(g、i、m、s、x 等),但底层交给 RE2,实现细节可能微小差异。

·schema 为 tencentdb,建议将 tencentdb 加入 search_path 或显式写 tencentdb.regexp_xxx。

三、创建插件

CREATE EXTENSION tencentdb_regex;– 可选:加入搜索路径以便直接写 regexp_replace(…)SET search_path = tencentdb, public;SELECT extname, extversion FROM pg_extension WHERE extname = 'tencentdb_regex';

四、函数清单

以下函数均有 tencentdb.regexp_* 与 tencentdb_regexp_* 两种命名。

五、regexp_replace

tencentdb.regexp_replace(source text, pattern text, replacement text) RETURNS text;tencentdb.regexp_replace(source text, pattern text, replacement text, flags text) RETURNS text;

作用等价于主干 regexp_replace。flags 常用值:

·g:全局替换(默认仅第一处)。

·i:忽略大小写。

·m:多行模式(^/$ 匹配行首/行尾)。

六、regexp_match / regexp_matches

tencentdb.regexp_match(source text, pattern text) RETURNS text[];tencentdb.regexp_match(source text, pattern text, flags text) RETURNS text[];tencentdb.regexp_matches(source text, pattern text) RETURNS SETOF text[];tencentdb.regexp_matches(source text, pattern text, flags text) RETURNS SETOF text[];

regexp_match 返回首个匹配的捕获组数组;regexp_matches 是 SRF,返回所有匹配(配合 g flag)。

七、regexp_split_to_array / regexp_split_to_table

tencentdb.regexp_split_to_array(source text, pattern text) RETURNS text[];tencentdb.regexp_split_to_array(source text, pattern text, flags text) RETURNS text[];tencentdb.regexp_split_to_table(source text, pattern text) RETURNS SETOF text;tencentdb.regexp_split_to_table(source text, pattern text, flags text) RETURNS SETOF text;

按 pattern 分割字符串。前者返回数组,后者以 SRF 返回每段。

八、regexp_extract

tencentdb.regexp_extract(source text, pattern text, group_id integer) RETURNS text;tencentdb.regexp_extract(source text, pattern text, group_id integer, flags text) RETURNS text;

返回首次匹配中第 group_id 个捕获组(0表示整段匹配)。无匹配或该组未参与匹配时返回 NULL。

九、regexp_count

tencentdb.regexp_count(source text, pattern text) RETURNS integer;tencentdb.regexp_count(source text, pattern text, flags text) RETURNS integer;

返回 pattern 在 source 中的匹配次数。

十、regexp_like

tencentdb.regexp_like(source text, pattern text) RETURNS boolean;tencentdb.regexp_like(source text, pattern text, flags text) RETURNS boolean;

判定是否存在至少一次匹配。等价于 source ~ pattern / source ~* pattern,但走 RE2。

十一、使用示例

CREATE EXTENSION IF NOT EXISTS tencentdb_regex;SET search_path = tencentdb, public;– 1) 全局替换(RE2 版),大小写不敏感SELECT regexp_replace('Hello World, hello RE2', 'hello', 'hi', 'gi');– 2) 抽取所有 URL 主机部分SELECT regexp_matches( 'see http://a.com and https://b.io/xyz', '(?i)https?://([^/\\s]+)', 'g');– 3) 分割为表SELECT regexp_split_to_table('a1b22c333d', '[0-9]+') AS part;– 4) 抽取第 N 个分组SET search_path = tencentdb, public;SELECT regexp_extract('user_id=42; name=alice', 'user_id=([0-9]+); name=([a-z]+)', 2);– alice– 5) 计数SELECT regexp_count('aaa bbb aa cc aaaa', 'a+');– 6) 存在性SELECT regexp_like('info@tencent.com', '^[\\w.+-]+@[\\w-]+\\.[\\w.-]+$');

与主干函数并存:由于均在 tencentdb schema 下,业务可以按需选择,例如:

— 明确走 RE2SELECT tencentdb.regexp_replace(col, pat, rep, 'g') FROM tbl;– 依然使用主干SELECT pg_catalog.regexp_replace(col, pat, rep, 'g') FROM tbl;

赞 (0)
上一篇 4天前
下一篇 4天前