首页 > 解决方案 > 如何在 Postgres 中为文本定义正则表达式

问题描述

请帮助为这种情况定义 Postgres 正则表达式:

我有字符串字段:

union all select 'AbC-345776-2345' /*comment*/ union all select 'Fgr-sdf344-111a' /*BN34*/ some text union all select 'sss-sdf34-123' /*some text*/ some text

为方便起见,这里是 select 语句中的相同文本:

select 'union all select ''AbC-345776-2345'' /*comment*/ union all select ''Fgr-sdf344-111a'' /*BN34*/ some text union all select ''sss-sdf34-123'' /*some text*/ some text' as str

我需要从这个混乱的文本中获取“...”中的唯一值,并将其选择到单独的行中,如下所示:

AbC-345776-2345
Fgr-sdf344-111a
sss-sdf34-123

模式:'前 2-3 个字母 - 几个字母和数字 - 几个字母和数字'

我创建了这个选择,但它也包含所有评论和“sometext”:

select regexp_split_to_table(trim(replace(replace(replace(replace(t1.str,'union all select',''),'from DUAL',''),chr(10),''),'''','') ), E'\\s+')
from (select 'union all select ''AbC-345776-2345'' /*comment*/ union all select ''Fgr-sdf344-111a'' /*BN34*/ some text union all select ''sss-sdf34-123'' /*some text*/ some text' as str) t1; 

标签: regexpostgresql

解决方案


以下应该做到这一点:

select (regexp_matches(str, $$'([a-zA-Z]{2,3}-[a-zA-Z0-9]+-[a-zA-Z0-9]+)'$$, 'g'))[1]
from the_table;

给定您返回的样本数据:

regexp_matches 
---------------
AbC-345776-2345
Fgr-sdf344-111a
sss-sdf34-123  

正则表达式检查您在单引号内指定的模式。通过使用一个组(...),我从结果中排除了单引号。

regexp_matches()为每个匹配返回一行,包含匹配数组。但是由于正则表达式只包含一个组,所以数组的第一个元素是我们感兴趣的。

我使用美元引用来避免转义正则表达式中的单引号

在线示例


推荐阅读