如何用regexp_extract提取delivery|或order|后的首个数字序列?
正确提取指定前缀后数字序列的正则写法
问题出在你原来的正则捕获组设计上——你把整个delivery|数字或order|数字放进了捕获组1,自然返回的是完整的前缀加数字串。要直接拿到数字,我们可以调整正则的捕获组结构,让目标数字成为唯一的捕获组。
最优解决方案
使用非捕获组包裹前缀部分,只捕获后面的数字序列:
select regexp_extract('delivery|1111111|22222222', '(?:delivery|order)\\|(\\d+)', 1); select regexp_extract('order|22222222|11111111', '(?:delivery|order)\\|(\\d+)', 1);
执行后会分别返回1111111和22222222,完全符合你的需求。
为什么这个写法有效?
(?:delivery|order):这是非捕获组(?:标识),它会匹配delivery或order但不会将这部分内容存入捕获组,避免占用捕获组编号。\\|:匹配竖线符号(因为竖线在正则里是分支符,所以需要转义)。(\\d+):这是唯一的捕获组,专门捕获前缀后面的连续数字序列,也就是你最终想要的结果。
原写法的问题分析
你之前的正则(delivery\\|(\\d+)|order\\|(\\d+))中:
- 捕获组1是整个匹配的
delivery|数字或order|数字 - 捕获组2对应
delivery后的数字,捕获组3对应order后的数字
所以当你指定取组1时,自然返回的是完整的前缀加数字串,而不是单独的数字。
备选方案(多捕获组判断)
如果你不想用非捕获组,也可以通过判断多个捕获组的非空值来获取结果(适合某些对非捕获组支持有限的场景):
select coalesce( regexp_extract('order|22222222|11111111', 'delivery\\|(\\d+)', 1), regexp_extract('order|22222222|11111111', 'order\\|(\\d+)', 1) );
但这种写法需要两次正则匹配,效率不如第一种方案高,更推荐使用非捕获组的写法。
内容的提问来源于stack exchange,提问作者Evgenii
相关产品推荐
相关产品推荐

