如何在PostgreSQL中提取字符串里完全由大写字母组成的单词
提取全大写单词(缩写)的正确SQL写法
你原来的REGEXP_REPLACE写法会把所有大写字母一股脑拼起来,根本区分不了是全大写的缩写单词,还是首字母大写的普通单词。要精准提取独立的全大写单词,得用正则匹配被单词边界/字符串首尾包裹的连续大写字母序列,还能按需过滤掉单个大写字母(比如示例里的"I"就不会被误提)。
下面是主流数据库的具体实现:
PostgreSQL
用REGEXP_MATCHES提取匹配项,再转成字符串:
SELECT title, array_to_string(REGEXP_MATCHES(title, '\b[A-Z]{2,}\b', 'g'), '') AS acronym FROM your_table;
\b:锁定单词边界,确保提取的是独立单词[A-Z]{2,}:匹配至少2个连续大写字母(要包含单个大写字母就把{2,}改成+)'g':全局匹配,一行有多个缩写会直接拼接(比如"BTW LOL"会得到"BTWLOL")
要是想把多个缩写用逗号分开,就这么写:
SELECT title, string_agg(match, ', ') AS acronyms FROM your_table, REGEXP_MATCHES(title, '\b[A-Z]{2,}\b', 'g') AS matches(match) GROUP BY title;
MySQL(8.0+)
提取第一个匹配的缩写用REGEXP_SUBSTR:
SELECT title, REGEXP_SUBSTR(title, '[A-Z]{2,}(?= |$|\\W)') AS acronym FROM your_table;
要提取所有缩写并拼接,得用递归CTE:
WITH RECURSIVE cte AS ( SELECT title, REGEXP_SUBSTR(title, '[A-Z]{2,}', 1, 1) AS acronym, 1 AS idx FROM your_table WHERE REGEXP_SUBSTR(title, '[A-Z]{2,}', 1, 1) IS NOT NULL UNION ALL SELECT cte.title, REGEXP_SUBSTR(cte.title, '[A-Z]{2,}', 1, cte.idx + 1), cte.idx + 1 FROM cte WHERE REGEXP_SUBSTR(cte.title, '[A-Z]{2,}', 1, cte.idx + 1) IS NOT NULL ) SELECT title, GROUP_CONCAT(acronym SEPARATOR '') AS acronym FROM cte GROUP BY title;
SQL Server
用反向替换的方式提取:
SELECT title, TRIM(REGEXP_REPLACE(title, '[^A-Z]*(?<![A-Z])[A-Z]{1}(?![A-Z])[^A-Z]*|[^A-Z]+', '', 'g')) AS acronym FROM your_table;
或者拆分单词后筛选再拼接:
SELECT title, STRING_AGG(value, '') AS acronym FROM your_table CROSS APPLY STRING_SPLIT(title, ' ') WHERE value LIKE '[A-Z][A-Z]%' AND value NOT LIKE '%[^A-Z]%' GROUP BY title;
测试示例数据
拿PostgreSQL的第一种写法跑你的示例,输出完全符合预期:
| title | acronym |
|---|---|
| I will leave ASAP | ASAP |
| David James is LOL | LOL |
| BTW I went home | BTW |
| Please RSVP today | RSVP |
内容的提问来源于stack exchange,提问作者SpenceM
相关产品推荐
相关产品推荐

