【问题标题】:How to use Postgres Regex Replace with a capture group如何使用 Postgres 正则表达式替换捕获组
【发布时间】:2020-12-28 02:34:26
【问题描述】:

正如上面的标题所示,我试图在 postgres 查询中引用捕获组以进行正则表达式替换。我读过 regex_replace 不支持使用正则表达式捕获组。我使用的正则表达式是

r"(?:[\s\(\)\=\)\,])(username)(?:[\s\(\)\=\)\,])?"gm

上面的正则表达式几乎可以满足我的需要,但我需要了解如何仅在捕获组也捕获某些内容时才允许匹配。如果“用户名”恰好是单词的子字符串,则不存在应该匹配的情况。通过确保它被上述之一包围,我可以更加自信地确保它是一个用户名。

一个正则表达式的示例应用程序在 postgres 中是这样的(当然我会做一个更新和一个选择):

select *, REGEXP_REPLACE(reqcontent,'(?:[\s\(\)\=\)\,])(username)(?:[\s\(\)\=\)\,])?' ,'NEW-VALUE', 'gm') from table where column like '%username%' limit 100;

如果可以提供更多上下文,请告诉我。我还发现了类似的帖子 (postgresql regexp_replace: how to replace captured group with evaluated expression (adding an integer value to capture group)),但更多的是关于将值拼接回去,我认为并不能完全回答我的问题。

正则表达式适用的更多上下文和示例值。下面的文本可能看起来很熟悉,这些是 Jira 中的 JQL 过滤器。我们正在寻找更新我们的用户名及其在包含过滤器的表中的所有出现。下面是几个过滤器的例子。我们最初只是在进行查找替换,但这不起作用,因为我们有一些只有两个字符的用户名,并且它与非用户名匹配(例如 je(用户名)会在找到单词 project 的位置放置一个新值这完全使 JQL/String 格式错误,导致类似 proNEW-VALUEct = balh blah)

type = bug AND status not in (Closed, Executed) AND assignee in (test, username)

assignee=username

assignee = username

回答的定义:

  • 仅当“用户名”被其中一个特殊项包围时才会匹配该用户名的正则表达式
  • 一种在 postgres 查询中正则表达式/替换该用户名的方法。

【问题讨论】:

  • Postgres 确实支持使用REGEXP_REPLACE 的捕获组。你能告诉我们一些关于这个冗长的正则表达式模式应该做什么,可能通过添加一些示例数据吗?
  • @TimBiegeleisen 感谢您的回复。我在上面提供了更多上下文并添加了一些文本示例,如果可以提供更多上下文,请告诉我。

标签: regex postgresql jira


【解决方案1】:

捕获组用于保持重要的信息位与正则表达式匹配。

在要保留在结果中的字符串部分周围使用捕获组,并在替换中使用它们的占位符:

REGEXP_REPLACE(reqcontent,'([\s\(\)\=\)\,])username([\s\(\)\=\)\,])?' ,'\1NEW-VALUE\2', 'gm')

或使用环视:

REGEXP_REPLACE(reqcontent,'(?<=[\s\(\)\=\)\,])(username)(?=[\s\(\)\=\)\,])?' ,'NEW-VALUE', 'gm')

或者,在这种情况下,使用单词边界来确保仅在特殊字符内替换单词:

REGEXP_REPLACE(reqcontent,'\yusername\y' ,'NEW-VALUE', 'g')

【讨论】:

  • postgres 正则表达式似乎不支持环顾四周。正则表达式不能匹配单词中的单个字母,但必须确保整个用户名都被这些特殊字符包裹,然后才有效。那有意义吗?例如,如果我们有两个案例。 “project = myProject” 如果我正在搜索用户“j”(用户名),那么它无法匹配项目中的 j 只有当它被 ()=\s 包围时才能匹配。看来我作为“工作”示例发布的正则表达式实际上并没有像我想象的那样做,我将在上面更新我的描述
  • 似乎第一个答案可以通过将用户名包装在外部捕获组中来工作。这让我意识到我的正则表达式已关闭。我需要强制捕获组匹配,如果不匹配,则不应将其视为匹配。
  • 是的,捕获组更常见,并且通常被所有正则表达式支持,这就是为什么它是第一个建议的解决方案。
  • @CoreySmith 使用单词边界,REGEXP_REPLACE(reqcontent,'\yusername\y' ,'NEW-VALUE', 'gm')
  • 要标记这是正确的。最终答案是 ([\s()\=)\,])\yusername\y([\s()\=)\,])?使用单词边界并在 REGEX_REPLACE(column, '([\s()\=)\,])\bbhauwd\b([\s()\=)\,]) 之类的查询中使用, '\1NEW-VALUE\2', 'gm')。感谢您的帮助
猜你喜欢
  • 2015-08-06
  • 1970-01-01
  • 2014-06-19
  • 2010-11-19
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
相关资源
最近更新 更多