正则表达式根据字符串内容匹配不同的组

时间:2017-02-02 09:36:29

标签: regex postgresql

要求

我有一个Postgres列,其中包含两种形式的值:个人和公司名称。个人姓名包含逗号,而公司名称则不包含。

_owner_titlecase
-------------------------
McCartney, James Paul
Lennon, John Winston Ono
Harrison, George
Starkey, Richard
The Beatles

我必须生成一个仅缩写个人姓名的查询,如下所示:

regexp_replace
-------------------------
McCartney, J P
Lennon, J W O
Harrison, G
Starkey, R
The Beatles

背景

经过一些性能测试后,我发现我无法使用CASE来区分两种行类型(如CASE WHEN _owner_titlecase ~ ',' regexp_replace...中所述)。所以我希望有一种方法来编写一个可以区别对待这两种类型的正则表达式。

previously asked关于如何处理个人姓名的缩写部分,现在使用(^\w+)|\Y\w正则表达式如下:

, regexp_replace(_owner_titlecase
    , '(^|;\s+)(\w+)|\Y\w'
    , '\1', 'g')

现在,我已扩大范围以查看公司名称,当然The Beatles缩写为The B

\Y是一个Postgres正则表达式字符类,我学习了here,它只匹配一个不是单词开头或结尾的点。虽然特殊的Postgres类看起来可以在这种情况下使用,但实际上使用通用的正则表达式功能实际上很有用,所以我可以在regex101.com这样的地方测试它们。目前我唯一的Postgres测试平台有点尴尬,并没有提供调试帮助。

整个故事是我们有一个CartoDB地图,我们想要在其上叠加一个包含属性所有者名称的图层。一些属性靠得很近,所有者名称列表可能很长,因此需要缩写。

1 个答案:

答案 0 :(得分:1)

我建议您使用

regexp_replace(_owner_titlecase,
     '^([^,]*)$|(^|;\s+)([\w\u0027]+)|\Y\w',
     '\1\2\3', 'g')

关键是你只需要删除前面带有单词char的任何单词char,并保留其他所有内容。因此,任何异常(您需要保留的文本)都可以作为捕获的替代分支添加到您需要删除的模式之前。

^([^,]*)$部分仅匹配并捕获由,以外的0 +字符组成的字符串,并使用\1将其恢复为替换结果。