You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL中使用正则表达式拆分包含数值(整数/浮点数)的字符串

在PostgreSQL中用正则拆分字符串与数值混合文本

我来帮你搞定这个混合文本拆分的问题,分单段数值和多段数值两种场景逐一说明:

单段数值场景(兼容整数/小数)

你之前用的regexp_match语句只适配整数,是因为\d+只能匹配连续数字,没法识别小数部分。我们只需要把数值匹配的正则调整成支持小数的格式就行:

适配整数的例子

SELECT regexp_match('abcd1234567ef', '(.*?)(\d+(?:\.\d+)?)(.*)');

返回结果:{abcd,1234567,ef}

适配小数的例子

SELECT regexp_match('abcd1234567.89ef', '(.*?)(\d+(?:\.\d+)?)(.*)');

返回结果:{abcd,1234567.89,ef}

正则说明

  • (.*?):非贪婪匹配开头的非数值字符串,直到遇到第一个数字就停止,避免把后面的内容也吞进去
  • (\d+(?:\.\d+)?):核心的数值匹配部分,\d+匹配整数部分,(?:\.\d+)?是可选的小数段(用非捕获组(?:...)避免生成多余的分组)
  • (.*):匹配数值后面剩下的所有字符串

多段数值场景

如果你的文本里有多处数值(比如abcd12efg34567hij),需要拆分出所有交替的字符串和数值段,可以用regexp_matches配合全局匹配标志g,再用unnest把结果展开成行:

拆分所有字符串/数值段(包括小数)

SELECT unnest(regexp_matches('abcd12efg34567hij', '([^\d]+)|(\d+(?:\.\d+)?)', 'g')) AS split_parts
WHERE split_parts IS NOT NULL;

返回结果:

split_parts
------------
abcd
12
efg
34567
hij

如果你的需求允许把相邻的非数值段合并(比如得到abcd、12efg、34567、hij),可以换一种思路:先按数值拆分字符串,再把拆分后的非数值段和数值段对应拼接。不过更简单的是用下面的语句,先提取所有数值位置,再拆分:

允许合并相邻非数值段的写法

WITH data AS (
  SELECT 'abcd12efg34567hij' AS input_str
),
numbers AS (
  SELECT 
    regexp_matches(input_str, '\d+(?:\.\d+)?', 'g') AS num,
    generate_series(1, regexp_count(input_str, '\d+(?:\.\d+)?')) AS idx
  FROM data
),
parts AS (
  SELECT 
    split_part(input_str, num[1], idx) AS str_part,
    num[1] AS num_part,
    idx
  FROM data, numbers
)
SELECT 
  CASE WHEN idx = 1 THEN str_part ELSE NULL END AS part,
  num_part AS part,
  CASE WHEN idx = (SELECT MAX(idx) FROM numbers) THEN split_part(input_str, num[1], idx+1) ELSE NULL END AS part
FROM parts
UNION ALL
SELECT split_part(input_str, num[1], idx+1) AS part
FROM data, numbers
WHERE idx = (SELECT MAX(idx) FROM numbers)
ORDER BY idx

不过这个写法稍复杂,如果你对两种拆分结果都接受,其实第一种全局匹配的写法更简洁好用。

内容的提问来源于stack exchange,提问作者Shh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:17:50