PHP 正则表达式 - 替换但从替换字符串中获取数值

PHP regex - replace but get numeric value from replaced string

我有一些 HTML 包含多个 HTML 评论,每个评论中都有一个表格。我正在尝试使用 preg_replace 将这些注释和其中的表单替换为表单 [CONTACT_FORM_X] 中的标签,其中 X 是表单的数字 ID。

$str = 'blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_1] -->some form goes here<!-- CONTACT FORM END 1 --> blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_2] -->another form goes here<!-- CONTACT FORM END 2 -->';

$replace = preg_replace('/<!-- CONTACT FORM START \[CONTACT_FORM_\d\] -->.*<!-- CONTACT FORM END \d -->/', '[CONTACT_FORM_X]', $str);
echo $replace;

所以:

<!-- CONTACT FORM START [CONTACT_FORM_1] -->some form goes here<!-- CONTACT FORM END 1 -->

应完全替换为 [CONTACT_FORM_1]

还有..

<!-- CONTACT FORM START [CONTACT_FORM_2] --> another form goes here<!-- CONTACT FORM END 2 -->

应完全替换为 [CONTACT_FORM_2]

如果我 运行 我上面的代码我得到:

blah blah blah [CONTACT_FORM_X]

所以我的问题是:

  1. 如何获取 \d 的值,然后用它代替我目前在 preg_replace

  2. 中使用 X 的位置
  3. 我的代码似乎只替换了其中一种形式,而不是两种形式。我如何调整 preg_replace 以允许多次替换

preg_replace 将替换所有匹配项(它是全局的)。 .* 是贪心的,它匹配 <!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] 之后的所有内容,直到 <!-- CONTACT FORM END \d -->。要捕获值,请使用 ().

所以尝试:

.*?<!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] -->.*?<!-- CONTACT FORM END \d -->

或者,如果您想确保匹配相同的关闭联系表,请使用反向引用:

.*?<!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] -->.*?<!-- CONTACT FORM END  -->

如果要保留前面的内容,则应删除开头的.*?。我不清楚那位的意图是什么。从 Should be replaced entirely with [CONTACT_FORM_2] 我解释为这是唯一应该保留的内容。

正则表达式演示:https://regex101.com/r/kS2nK6/1

PHP 用法:

<?php
$str = 'blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_1] -->some form goes here<!-- CONTACT FORM END 1 --> blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_2] -->another form goes here<!-- CONTACT FORM END 2 -->';

$replace = preg_replace('/.*?<!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] -->.*?<!-- CONTACT FORM END \d -->/', '[CONTACT_FORM_]', $str);
echo $replace;

PHP 演示:https://eval.in/611232

如下更改您的模式和替换字符串:

$pattern = '/<!-- CONTACT FORM START \[CONTACT_FORM_(\d+)\] -->.*<!-- CONTACT FORM END  -->/';
$replace = preg_replace($pattern, '[CONTACT_FORM_]', $str);

Live demo

工作原理

  • 将您以后要重复使用的任何文本放在括号中。这称为 捕获组 。所以我在你的模式中将 \d 更改为 (\d+)+ 只允许两位数+数字)
  • 要从模式中返回第一个捕获的组,请使用 </code>。将 <code>CONTACT FORM END \d 更改为 CONTACT FORM END 会告诉正则表达式引擎,一旦您用 START 中看到的相同数字点击 END,要替换的字符串就会停止。如果没有这个,引擎会将所有内容替换到最后 CONTACT FORM END。这就是为什么你只得到一个替代品。
  • 在替换字符串中,使用</code> 来引用第一个捕获的组。这就是为什么将 <code>CONTACT_FORM_X 更改为 CONTACT_FORM_ 在替换字符串中放置正确数字的原因。