Postgres regexp_replace:无法用第一个捕获的组替换源文本
Posted
技术标签:
【中文标题】Postgres regexp_replace:无法用第一个捕获的组替换源文本【英文标题】:Postgres regexp_replace: inability to replace source text with first captured group 【发布时间】:2021-03-05 18:42:00 【问题描述】:使用 PostgreSQL,我无法设计正确的正则表达式模式来实现使用 regexp_replace 的 SQL 语句的所需输出。
我的源文本由几个分散的文本块组成,格式为“PU*”,后跟一个格式为“YYYY-MM”的日期字符串,例如“PU*2020-11”。这些块被不可预知的任意文本字符串(包括“PU*”的其他实例,后跟上述日期字符串格式,例如“PU*2017-07”)、空格和换行符包围。
我希望用“YYYY-MM”文本模式的第一个实例替换整个源文本。在上面的示例中,所需的输出将是“2020-11”。
目前,我的搜索模式会产生正确的替换文本来代替第一个捕获组,但不幸的是,第一个捕获组之后的所有文本也无意中出现在输出中,这不是所需的输出。
具体来说:
版本:postgres (PostgreSQL) 13.0
一个更复杂的源文本示例:
First line
Exec committee
PU*2020-08
PU*2019-09--cancelled
PU*2017-10
added by Terranze
到目前为止我的模式:
(\s|\S)*?PU\*(\d4-\d2)(\s|\S*)*
当前 SQL 语句:
select regexp_replace('First line\nExec committee; PU*2020-08\nPU*2019-09\nPU*2017-10\n\nadded by Terranze\n', '(\s|\S)*?PU\*(\d4-\d2)(\s|\S*)*', '\2') as _regex;
https://regex101.com/ 上的电流输出
2020-08
psql 上的当前输出
_regex
───────────────────────────────────────────────────────────────────
2020-08\nPU*2019-09--cancelled\nPU*2017-10\n\nadded by Terranze\n
(1 row)
期望的输出:
2020-08
任何帮助表示赞赏。谢谢--
【问题讨论】:
【参考方案1】:这个表达式怎么样:
'^.*?PU\*(\d4-\d2).*$'
【讨论】:
感谢您的快速回复!好吧,我意识到我在描述问题的方式上犯了一个错误。我的示例复杂源文本包含换行符,我认为将 '\n's 放在源文本中会模拟实际的换行符,但我现在意识到它没有。正则表达式引擎将这些解释为文字'\n'。 所以我将源文本更新为真正的多行,而您的模式在这种情况下不起作用。你知道另一种可能有效的模式吗?谢谢-- 对不起,我收回;您的解决方案有效!我知道 ^ 标记字符串的开头, $ 标记结尾,但我不知道为什么在这种情况下它们是必要的。 很棒的@WDock。那么,您能否将 awswer 标记为已接受。 :) 关于您的问题,首先需要 ^ 和 $ 创建一个固定的锚点,以便在字符串末尾以“最贪婪”的方式完成捕获,反之亦然一开始就接近。希望这很清楚以上是关于Postgres regexp_replace:无法用第一个捕获的组替换源文本的主要内容,如果未能解决你的问题,请参考以下文章
使用 postgres regexp_replace() 替换字符串中的整数
Postgres regexp_replace:无法用第一个捕获的组替换源文本
正则表达式使用 postgres regexp_replace() 用单引号替换反斜杠和单引号