Preg_replace() 使用非捕获组添加到字符串

Preg_replace() to add to string using non-capturing group

我有一段 HTML 标记,我需要为其添加特定的 CSS 规则。 HTML 是这样的:

<tr>
<td style="color:#555555;padding-top: 3px;padding-bottom: 20px;">In order to stop receiving similar emails, simply remove the relevant <a href="https://domain.tld/dashboard/" target="_blank">saved search</a> from your account.</td>
</tr>

正如你所看到的td已经包含了一个style标签,所以我的想法是匹配它的最后一个;并用;替换它加上我需要添加的规则...

问题是,虽然我使用了适当的非捕获组,但我仍然不知道如何正确地做到这一点...请看一下这个实验:https://regex101.com/r/qlVq6A/1

(<td.*style=".*)(;)(".*>)(?:In order to stop receiving)

另一方面,当我为最后一部分分配一个捕获组时(那里的英文文本只是为了确定我对哪个 td 感兴趣)它工作正常,但我觉得这是一种间接的方式来完成这项工作......看看这个实验:https://regex101.com/r/qhVatN/1

(<td.*style=".*)(;)(".*>In order to stop receiving)

有人可以向我解释为什么第一条路线不起作用吗?基本上,为什么非捕获组仍然捕获其中的文本...

在你的第二个模式中,你使用了 3 个捕获组,你使用了你想要在替换中添加的样式,第 3 个组包含 In order to stop receiving,它将在替换中使用第 3 个组后出现。

但是在你的第一个模式中,你使用了一个非捕获组 (?: 并且它将 匹配 但不是替换的一部分。

请注意,当使用像这样的非捕获组时,您完全可以省略它,因为像这样的分组本身没有例如量词或交替没有其他目的。

您可以为示例字符串使用模式,但这很容易出错,使用 DOM 解析器是更好的选择。

仅使用 2 个捕获组编写模式的方法:

(<td[^>]*\bstyle="[^"]*;)([^"]*">In order to stop receiving)

替换使用中:

font-size: 80%;

说明

  • ( 捕获 组 1
    • <td[^>]* 匹配 <td 然后可选地重复除 >
    • 之外的任何字符
    • \bstyle="[^"]*; 匹配 style=" 然后可选地重复匹配除 " 之外的任何字符,然后匹配最后一个分号(注意它现在是第 1 组的一部分)
  • ) 关闭组 1
  • ( 捕获 第 2 组
    • [^"]*">In order to stop receiving 可选择重复匹配除 : 之外的任何字符,然后匹配 "> 后跟预期的文本
  • ) 关闭组 2

看到一个regex demo


另一种不使用捕获组编写模式的选项使用 \K 忘记到目前为止匹配的内容,并使用正向前瞻 (?= 断言右侧的预期文本:

<td[^>]*\bstyle="[^"]*;\K(?=[^"]*">In order to stop receiving)

再看一个regex demo