【问题标题】:preg_replace confusion [duplicate]preg_replace 混淆[重复]
【发布时间】:2020-04-24 00:09:58
【问题描述】:

在包含一些 html 的字符串中,我想查找并替换每次出现的 <h1-6> 标记,包括它后面的任何内容,直到另一个 <h1-6> 标记或直到 html 字符串的结尾。

我的模式:<h\d.+?(?=<h\d)

使用 /gs 标志,此模式在 this online testing tool 上运行良好。

但是,在服务器端测试中,我只能使我的模式匹配第一次出现,而其余的被忽略。

PHP Manual 状态:

搜索 matches 的主题并将其替换为 them 替换。

Another post answer 提及:

preg_replace() 默认会执行全局替换

根据上述,如果更改为/<h\d.+?(?=<h\d)/s,我的服务器端模式应该可以工作,但由于某种原因,它仍然只替换第一次出现。

完整代码:

$html = get_html_string();
$pattern = '/<h\d.+?(?=<h\d)/s';
$replace = '<div>$0</div>';
$html = preg_replace($pattern, $replace, $html);
return $html;


更新:

看起来我的 html 示例与网站上的实际 html 有所不同。因此,我确保将我想要直接操作的字符串复制到在线测试工具中。现在很明显匹配有效,但实际问题是最后一个匹配不包括在内。见this updated test

感谢尼克的回答和其他人的参与。

【问题讨论】:

  • 在这个例子中你不是只针对 h2
  • 如果我真的明白了,你想用这种格式找到所有出现 **>
  • 对我来说,它应该可以工作。请向我们展示输入示例。
  • 原来样本输入在某种程度上有所不同。我用详细信息更新我的帖子。

标签: php regex preg-replace


【解决方案1】:

你有几个问题:

  1. 您需要g(全局)标志来获得多个匹配项
  2. 您需要添加$(字符串结尾)作为前瞻的替代,以便它可以匹配到最后一个&lt;hn&gt; 标记的字符串结尾。

这应该做你想做的:

<h\d.+?(?=<h\d|$)

Demo on regex101

在 PHP 中:

preg_match_all('/<h\d.+?(?=<h\d|$)/s', $html, $matches);
print_r($matches[0]);

输出:

Array
(
    [0] => <h1> attribute="whatever">asiponfpweg ihnasegio</h1>asd
<p>whatever</p>
<img src=""></img>
    [1] => <h3> attribute="whatever">asiponfpweg ihnasegio</h3>
<p>whatever</p>
<p>whatever</p>
    [2] => <h1><span> attribute="whatever">asiponfpweg ihnasegio</span></h3>
<p>whatever</p>
    [3] => <h3> attribute="whatever">asiponfpweg ihnasegio</h3>
)

Demo on 3v4l.org

【讨论】:

  • 我应该提到我正在尝试使用 preg_replace 来完成这项工作。我已经重写了我的问题。
  • @bewww 抱歉没有回复 - 这里已经是晚上了。我想你已经解决了,但同样的正则表达式可以在 preg_replace 上正常工作,请参阅 3v4l.org/K8h0P
猜你喜欢
  • 2010-10-12
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 2013-01-29
  • 2018-10-22
  • 2013-01-01
相关资源
最近更新 更多