为什么在使用正先行 (?=...) 时,regexp_matches 函数会得到空响应
Why do I get empty response for regexp_matches function while using positive lookahead (?=...)
为什么下面的代码 return 只是空括号 - {''}。如何让它 return 匹配字符串?
SELECT regexp_matches('ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT','(?=..CAA)','g');
预期输出为:
regexp_matches
----------------
{GCCAA}
{AACAA}
{AACAA}
{GTCAA}
(4 rows)
而是 return 如下:
regexp_matches
----------------
{""}
{""}
{""}
{""}
(4 rows)
我实际上有一个更复杂的查询,它需要正向前瞻以覆盖字符串中所有出现的模式,即使它们重叠。
Lookahead 是一个零宽度断言。它不匹配任何东西。如果您将正则表达式更改为正则表达式 match/capture,您将得到一个结果。为了匹配您的情况下后跟 CAA
的任意两个字符,可能不需要先行。
- 使用前瞻有一个问题,即前瞻本身不是匹配的一部分,但它允许重叠搜索
- 如果不使用前瞻,您将失去重叠搜索的能力。
使用 Powershell,您可以遍历前瞻返回的索引,并将其用作搜索字符串的索引以获取匹配项
$string = 'ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT'
$r = [regex]::new('(?=..CAA)')
$r.Matches($string) | % {$string.Substring($_.Index, 5)}
returns
GCCAA
AACAA
AACAA
GTCAA
我不知道如何将其转换为 PostgreSQL (或者如果可能的话)
嗯,这不是很漂亮,但你可以在没有正则表达式或自定义函数的情况下做到这一点。
WITH data(d) as (
SELECT * FROM (VALUES ('ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT')) v
)
SELECT substr(d, x, 5) AS match
FROM data
JOIN LATERAL (SELECT generate_series(1, length(d))) g(x) ON TRUE
WHERE substr(d, x, 5) LIKE '__CAA'
;
match
-------
GCCAA
AACAA
AACAA
GTCAA
(4 rows)
基本上,获取字符串的每五个字母切片并查看它是否匹配 __CAA。
您可以将 generate_series(1, length(d))
更改为 generate_series(1, length(d)-4)
,因为最后一个永远不会匹配,但如果匹配字符串的长度发生变化,您必须记得更新它。
更新:
显然它不会捕获断言内部,没关系,因为
您真正需要的是前 2 个字符,可以安全地
消费。它只会给你每行的前 2 个字符,但是
因为你知道最后3个,你可以很容易地加入集合元素
使用 CAA
常量。
试试这个
..(?=CAA)
大功告成。
如果我知道奇怪的 sql 语言,我可以向您展示如何进行连接。
输出现在应该是
match
-------
GC
AA
AA
GT
(4 rows)
这是重叠匹配所需的正则表达式。
(?=(..CAA))
https://regex101.com/r/eJ36zb/1
我认为您只需要捕获第 1 组的 sql 语句:
SELECT regexp_matches('ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT','(?=(..CAA))','g');
格式化正则表达式
(?=
( . . CAA ) # (1)
)
你的结果中出现空字符串的原因是
你没有给表达式任何消费和
没有什么可捕捉的。
也就是说,它在正确的地方匹配,但没有消耗或捕获任何东西。
所以,这样做允许重叠和捕获所以它
现在应该出现在输出中。
为什么下面的代码 return 只是空括号 - {''}。如何让它 return 匹配字符串?
SELECT regexp_matches('ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT','(?=..CAA)','g');
预期输出为:
regexp_matches
----------------
{GCCAA}
{AACAA}
{AACAA}
{GTCAA}
(4 rows)
而是 return 如下:
regexp_matches
----------------
{""}
{""}
{""}
{""}
(4 rows)
我实际上有一个更复杂的查询,它需要正向前瞻以覆盖字符串中所有出现的模式,即使它们重叠。
Lookahead 是一个零宽度断言。它不匹配任何东西。如果您将正则表达式更改为正则表达式 match/capture,您将得到一个结果。为了匹配您的情况下后跟 CAA
的任意两个字符,可能不需要先行。
- 使用前瞻有一个问题,即前瞻本身不是匹配的一部分,但它允许重叠搜索
- 如果不使用前瞻,您将失去重叠搜索的能力。
使用 Powershell,您可以遍历前瞻返回的索引,并将其用作搜索字符串的索引以获取匹配项
$string = 'ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT'
$r = [regex]::new('(?=..CAA)')
$r.Matches($string) | % {$string.Substring($_.Index, 5)}
returns
GCCAA
AACAA
AACAA
GTCAA
我不知道如何将其转换为 PostgreSQL (或者如果可能的话)
嗯,这不是很漂亮,但你可以在没有正则表达式或自定义函数的情况下做到这一点。
WITH data(d) as (
SELECT * FROM (VALUES ('ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT')) v
)
SELECT substr(d, x, 5) AS match
FROM data
JOIN LATERAL (SELECT generate_series(1, length(d))) g(x) ON TRUE
WHERE substr(d, x, 5) LIKE '__CAA'
;
match
-------
GCCAA
AACAA
AACAA
GTCAA
(4 rows)
基本上,获取字符串的每五个字母切片并查看它是否匹配 __CAA。
您可以将 generate_series(1, length(d))
更改为 generate_series(1, length(d)-4)
,因为最后一个永远不会匹配,但如果匹配字符串的长度发生变化,您必须记得更新它。
更新:
显然它不会捕获断言内部,没关系,因为
您真正需要的是前 2 个字符,可以安全地
消费。它只会给你每行的前 2 个字符,但是
因为你知道最后3个,你可以很容易地加入集合元素
使用 CAA
常量。
试试这个
..(?=CAA)
大功告成。
如果我知道奇怪的 sql 语言,我可以向您展示如何进行连接。
输出现在应该是
match
-------
GC
AA
AA
GT
(4 rows)
这是重叠匹配所需的正则表达式。
(?=(..CAA))
https://regex101.com/r/eJ36zb/1
我认为您只需要捕获第 1 组的 sql 语句:
SELECT regexp_matches('ATGCATGCATGCCAACAACAACCTGTCAAGTGAGT','(?=(..CAA))','g');
格式化正则表达式
(?=
( . . CAA ) # (1)
)
你的结果中出现空字符串的原因是
你没有给表达式任何消费和
没有什么可捕捉的。
也就是说,它在正确的地方匹配,但没有消耗或捕获任何东西。
所以,这样做允许重叠和捕获所以它
现在应该出现在输出中。