是否可以用正则表达式专门替换组的内容?

时间:2019-07-25 13:36:34

标签: regex

我需要在telegraf.conf文件的某个部分中找到,取消注释并替换变量值(使用Ansible):

  ## HTTP Basic Auth
  # username = "telegraf"
  # password = "metricsmetricsmetricsmetrics"

与此

  ## HTTP Basic Auth
    username = "myusername"
    password = "anotherpassword"

我能够找到原始的方块

(^.+HTTP Basic Auth\R.+)#( username = ").+("\R.+)#( password = ").+(")

并替换为

\1 \2myusername\3 \4anotherpassword\5

但是我发现将我不想替换的零件分组是非常违反直觉的,而不仅仅是需要修改的部分。就像我对表达式进行否定匹配以替换其他位一样。

另一个表达式将仅为需要编辑的部分创建组:

^.+HTTP Basic Auth\R.+(#) username = "(.+)"\R.+(#) password = "(.+)"

这也减少了一个组,我发现该表达式更易于阅读。 但是我找不到在线的替代表达式的文档或示例/解决方案,这些表达式或表达式明确指出了每个组的新内容。

这不是替代设计的工作方式,还是有实现此目的的方法?

2 个答案:

答案 0 :(得分:1)

正则表达式的唯一工作就是匹配模式。您稍后再来,对匹配模式的数据做一些有趣的事情,但是正则表达式本身仅匹配。

单个正则表达式只能匹配单个模式。您要替换字符串的两个部分,因此需要确定是否要在单个正则表达式中同时匹配用户名和密码,从而用单行代码处理替换,或者是否愿意将其分解为一种模式,这将简化正则表达式并需要两个单独的替换。

我认为也许您最缺少的帮助是lookaround groups。使用零宽度后向搜索组,您可以找到以模式为前缀的模式,而实际上并未“匹配”该前缀。

例如,如果我想找到以D为前缀的E,但是我只想匹配(并替换为D),则可以使用以下正则表达式:

(?<=E)D

提供以下输入:

ADBDCDED

我的正则表达式将仅匹配最后一个D。所有其他D都将失败,因为它们没有以E为前缀。但是,只有D被匹配,E没有被匹配。

Ansible似乎使用python正则表达式,因此您必须参考python's documentation了解可接受的模式。

不幸的是,python在回溯中仅支持固定长度的模式,这意味着您可以使用类似a|b之类的东西,而不能使用a*之类的东西。只要您确信您的用户名始终以username =

为前缀,我认为这对您来说不会有问题

长话短说,您可以使用类似的模式来找到您的用户名:

(?<=username = ")[^"]+

这将查找username = ",然后匹配以下所有字符,直到找到"

您也可以重复此密码模式:

(?<=password = ")[^"]+

答案 1 :(得分:0)

我要感谢https://stackoverflow.com/users/211627/jdb的有益讨论,但最终,这就是我目前认为直接回答问题的合理方法。随时发表评论。

严格在正则表达式中,可以使用大写或小写转换(对于组1分别为\ U \ 1和\ L \ 1)来修改匹配表达式中的组,但是没有其他标记可以对组的内容。

所以答案是否定的。要通过指示替换正则表达式来常规地修改匹配的正则表达式的各个部分,必须为不需要修改的部分创建组。在替换表达式中,通过依次放置原始组并在组之间引入修改后的文本来重新创建原始表达式。无需为要修改的零件创建组,因为这些组不会在替换正则表达式中引用。问题中指出的解决方案 $stmt->bind_param("s", $login_token); 举例说明了此过程。