Regex 在SQL中查找字符串中第n次出现的模式(Presto)

Regex 在SQL中查找字符串中第n次出现的模式(Presto),regex,presto,trino,Regex,Presto,Trino,我正在使用函数regexp\u extract在Presto SQL中编写一个查询 我有一个字符串,可能类似于以下示例: '1A2B2C3D3E' '1A1B2C2D3E' '1A2B1C2D2E' 我想做的是找到例如1[A-E]的第二次出现 如果我尝试 regexp_extract(col, '(1[A-E])(1[A-E])', 2) 这将适用于第二个示例(以及第一个示例,因为它不返回任何内容,因为没有第二个实例)。但是,对于第三个示例,这将失败。它什么也不返回。我知道这是因为我的正则表

我正在使用函数regexp\u extract在Presto SQL中编写一个查询

我有一个字符串,可能类似于以下示例:

'1A2B2C3D3E'
'1A1B2C2D3E'
'1A2B1C2D2E'
我想做的是找到例如1[A-E]的第二次出现

如果我尝试

regexp_extract(col, '(1[A-E])(1[A-E])', 2)
这将适用于第二个示例(以及第一个示例,因为它不返回任何内容,因为没有第二个实例)。但是,对于第三个示例,这将失败。它什么也不返回。我知道这是因为我的正则表达式正在搜索一个1[a-E],后面紧跟着另一个1[a-E]

于是我试着

regexp_extract(col, '(1[A-E])(.*)(1[A-E])', 3)

但这也不起作用。我不确定如何解释可能有1A1B2C或1A2B1C找到第二个1的事实。有什么帮助吗?

您不需要第二个捕获组
(.*)
来将两个捕获组保留在结果中,您可以选择匹配中间允许的字符

从我读到的文章中,您也可以考虑使用<代码> ReXExpExtupTyAuth/<代码>来获得所有匹配,如<代码> ReXExpReXix< /Cord>返回第一个匹配项。

由于示例数据由后跟字符a-E的数字组成,因此可以从字符类中排除与1匹配的字符,以防止过度匹配和回溯

(1[A-E])[02-9A-E]*(1[A-E])

如果使用单个捕获组获取第二个值也可以,则可以使用

1[A-E][02-9A-E]*(1[A-E])

第二种模式在最新版本的Trino()中确实有效:

正如其他人所评论的,第一次匹配或
*
不需要捕获组,您应该使用惰性量词以避免
*
急切地匹配第一次和最后一次匹配之间的所有字符:

带t(col)作为(
价值观
“1A2B2C3D3E”,
“1A1B2C2D3E”,
“1A2B1C2D2E”,
‘1A2B1C2D1E’)
选择regexp_extract(列,'1[A-E].*(1[A-E]),1)
从t

我不知道普雷斯托的情况,但你的第二种模式看起来应该行得通。唯一的问题是,您应该使用惰性量词(即,
*?
而不是
*
),否则组3将包含最后一个事件,而不一定是第二个事件。你说的“不起作用”到底是什么意思?你有什么结果吗?是什么让OP的原始模式“不起作用”呢?@41686d6564我认为使用
regexp\u extract
而不是
regexp\u extract\u all
,但我没有使用presto的经验。谢谢你的帮助。不幸的是,我编写这个查询的程序不允许我使用regex\u extract\u all。更糟糕的是,由于某些原因,您的解决方案在此程序中不起作用(即使我认为它是正确的)。在带有[0-9A-E]*的部分中,是否有排除1的方法?所以它只搜索0,2-9?对不起,我和你的关系不太好regex@user9592573“有排除1的方法吗?”这不正是这个答案中的第二个模式所做的吗?@user9592573如果第二个值也可以使用单个组,那么您可以使用
1[a-E][02-9A-E]*(1[a-E])
WITH t(col) AS (
  VALUES 
    '1A2B2C3D3E', 
    '1A1B2C2D3E',
    '1A2B1C2D2E')
SELECT regexp_extract(col, '(1[A-E])(.*)(1[A-E])', 3)
FROM t
 _col0
-------
 NULL
 1B
 1C
(3 rows)
 _col0
-------
 NULL
 1B
 1C
 1C
(4 rows)