从regexp_matches结果中获得第二场比赛

时间:2018-09-05 06:52:10

标签: sql regex postgresql

我有一个name列,看起来像这样:

'1234567 - 7654321 - some - more - text'

我需要获取一个字符串"7654321"。我坚持以下几点:

SELECT regexp_matches('1234567 - 7654321 - some - more - text', '\d+', 'g');

regexp_matches
----------------
{1234567}
{7654321}

(2 rows)

我该怎么办?也许有比regexp_matches更好的选择-我们很乐意考虑。谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用REGEXP_REPLACE

SELECT REGEXP_REPLACE('1234567 - 7654321 - some - more - text', '^\d+[^\d]+(\d+).*$', '\1');

输出

7654321

此正则表达式查找一个字符串,该字符串以一些数字(^\d+)开头,后跟一些非数字字符([^\d]+),然后是另一组数字((\d+))一定数量的字符,直到字符串(.*$)的结尾。第二组数字字符周围的()组成了一个捕获组,然后可以用\1在替换字符串中引用该捕获组。由于REGEXP_REPLACE仅替换与正则表达式匹配的字符串部分,因此有必要使正则表达式与 whole 字符串匹配,以便仅用所需数据替换它。

更新

如果在第一组数字之前有潜在的字符,则应将正则表达式更改为

^[^\d]*\d+[^\d]+(\d+).*$

更新2

如果开头可能只有一组数字,则必须使匹配第一部分为可选。我们可以使用一个非捕获组来做到这一点:

^[^\d]*(?:\d+[^\d]+)?(\d+).*$

这使得第一组数字上的匹配是可选的,因此如果不存在(即只有一组数字),则正则表达式仍将匹配。通过使用非捕获组(将?:添加到该组的开头,我们不需要从\1更改替换字符串。已更新SQLFiddle

答案 1 :(得分:1)

regexp_matches()返回一个表,因此您可以在from子句中将其与with ordinality选项一起使用:

SELECT t.value
from regexp_matches('1234567 - 7654321 - some - more - text', '\d+', 'g') with ordinality as t(value,idx)
where t.idx = 2;

请注意,value仍然是一个数组,要获取实际的数组元素,可以使用:

SELECT t.value[1]
from regexp_matches('1234567 - 7654321 - some - more - text', '\d+', 'g') with ordinality as t(value,idx)
where t.idx = 2;