要求
我有一个 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 map ,我们想在上面叠加一个包含属性(property)所有者姓名的图层。有些属性靠得很近,所有者姓名列表可能很长,因此需要缩写。
最佳答案
我建议你应该使用
regexp_replace(_owner_titlecase,
'^([^,]*)$|(^|;\s+)([\w\u0027]+)|\Y\w',
'\1\2\3', 'g')
要点是您只需要删除前面带有单词 char 的任何单词 char,并保留其他所有内容。因此,任何异常(您需要保留的文本)都可以作为捕获的替代分支添加到您需要删除的模式之前。
^([^,]*)$
部分仅匹配并捕获由 0+ 个字符组成的字符串,而不是 ,
,并且带有 \1
你在替换结果中恢复它。
关于正则表达式根据字符串内容匹配不同的组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41998639/