正则表达式匹配字符串除非后跟#

时间:2018-06-14 07:44:52

标签: regex postgresql replace

我正在尝试将#param添加到url中我想将它添加到所有尚未拥有#的网址以避免双重参数。我的网址看起来不像网址,它们是由车把参数组成的。

他们可能如下所示:

{{app.url}}
{{root.app.url}}
{{app.url}}#param
{{root.app.url}}#param

所以我想出了一个与把手标签匹配的正则表达式({{(root。)?app.url}})

唯一的问题是我以后使用regexp_replace(url, '({{(root\.)?app\.url}})', '\1#param')

我的结果如下:

{{app.url}}#param
{{root.app.url}}#param
{{app.url}}#param#param
{{root.app.url}}#param#param

我能想到的一个解决方案是分两步完成,第二步应该查找重复的#param #param并将其替换为单个#param。

但是我想知道是否有办法使用正则表达式来排除#后面的车把标签并完全取消匹配?

以下是一些例子: https://regex101.com/r/d3Zyvo/6

注意:这是用于postgressql更新查询。正则表达式是POSIX / PCRE。我必须使用带有反向引用的regex_replace,因为hanbdlebar标签之前和之后可能有内容,我根本无法连接param。 (见链接)。

1 个答案:

答案 0 :(得分:2)

您可以使用否定前瞻(?!#)

({{(root\.)?app\.url}})(?!#)
                       ^^^^^ 

请参阅regex demo

<强>详情

  • ({{(root\.)?app\.url}}) - 第1组(后来用替换模式中的\1引用):
    • {{ - {{ substring
    • (root\.)? - 可选的第2组,匹配1或0次root.
    • app\.url}} - 文字app.url}}子字符串
  • (?!#) - 如果在当前位置的右侧有一个#字符,则会导致匹配失败的否定前瞻。

请参阅Table 9-17. Regular Expression Constraints

  

(?!re)负向前瞻匹配任何没有子串匹配重新开始的点(仅限ARE)

PostgreSQL演示:

select regexp_replace('{{app.url}}
{{root.app.url}}
{{app.url}}#param
{{root.app.url}}#param',
                      '({{(root\.)?app\.url}})(?!#)',
                      '\1#param',
                      'g');

enter image description here