preg_match和替换功能 [已关闭]

preg_match and replace function [closed]

提问人:strejcekmichal 提问时间:10/27/2023 最后编辑:halferstrejcekmichal 更新时间:10/28/2023 访问量:82

问:


想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。

23天前关闭。

我希望您帮助preg_match和替换功能,我有这个:

$replacement="NEW TEXT";
<p data-edit="1">TEXT A</p>
<div data-edit="2">TEXT B</div>

我需要找到 div 或 p 或任何具有等于某个数字的 data-edit 属性的东西,在这种情况下例如 1 并替换里面的文本 $replacement。

php 替换

评论

0赞 Barmar 10/27/2023
不要使用正则表达式来解析 HTML。Use 或 simple-html-domDOMDocument
0赞 strejcekmichal 10/27/2023
我必须使用preg_match并替换
0赞 Chris Haas 10/27/2023
你试过什么吗?
0赞 Barmar 10/27/2023
然后展示你尝试过的内容。您应该能够使用捕获组来捕获标记,然后将其复制到替换标记中。$replacement
1赞 Barmar 10/27/2023
欢迎来到 Stack Overflow!如何向有家庭作业问题的学生提出家庭作业问题公开信

答:

-1赞 TSCAmerica.com 10/27/2023 #1

首先设置要替换的 HTML 内容和文本,确定 '' 属性定位中的特定编号,并使用正则表达式来隔离完整的 HTML 元素。此过程涉及捕获开始和结束标记,特别是精确定位具有与目标编号对应的“”属性的元素。然后利用 '' 调用回调函数,制作替换字符串并用新定义的文本替换原始元素内容。希望它有所帮助。data-editdata-editpreg_replace_callback

<?php

$replacement = "NEW TEXT";
$htmlContent = '
<p data-edit="1">TEXT A</p>
<div data-edit="2">TEXT B</div>
';

$targetNumber = 1;

$pattern = '/(<(p|div|any other tag)[^>]*data-edit="\s*' . preg_quote($targetNumber, '/') . '\s*"[^>]*>)(.*?)(<\/\2>)/i';

$newContent = preg_replace_callback($pattern, function ($matches) use ($replacement) {
    return $matches[1] . $replacement . $matches[4];
}, $htmlContent);

// Output the new content
echo $newContent;
?>

评论

0赞 mickmackusa 10/27/2023
首先,preg_replace_callback() 是矫枉过正。其次,使用函数来解析 HTML 是不可靠的。当 HTML 输入在引用、属性前缀、空格异常、类似于 HTML 的文本异常以及区分大小写问题方面存在偏差时,将来会出现令人头疼的问题。许多开发人员已经走上了 HTML 解析的正则表达式路径;最终,我们都了解到 DOM 解析器是更可靠的工具。preg_
1赞 mickmackusa 10/27/2023 #2

正则表达式不是用于解析 HTML 的可靠工具。最佳做法是利用合法的 HTML 解析器。在这种情况下,我发现 DomDocument 和 XPath 的组合是一种非常直接的方法。由于您的 HTML 没有(预期的)父元素,因此我将手动添加一个父标记,然后在字符串化结果时将其删除。div

XPath 查询表示在文档 () 中的任意深度,将任何元素 () 与属性 () 匹配。要定位特定值,请编写 like .//*data-edit[@data-edit]data-edit//*[@data-edit=2]

代码:(演示)

$replacement = 'NEW TEXT';
$html = <<<HTML
<p data-edit="1">TEXT A</p>
<div not-data-edit="3">TEXT C</div>
<div data-edit="2">TEXT B</div>
HTML;

$dom = new DOMDocument; 
$dom->loadHTML('<div>' . $html . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//*[@data-edit]") as $node) {
    $node->nodeValue = $replacement;
}
var_export(substr($dom->saveHTML() ,5, -7));

请注意,在我的演示中,代码完美地区分了合格/不合格的属性。data-edit

'<p data-edit="1">NEW TEXT</p>
<div not-data-edit="3">TEXT C</div>
<div data-edit="2">NEW TEXT</div>'

正则表达式必须付出更大的努力来防范边缘案件。

这里有一个有点相关的答案,有类似的见解:preg_replace img src 到 data-src 堆栈溢出 (PHP)


更具体地说,关于在查询中指定一个数字,请写如下。演示data-edit2

$replacement = 'NEW TEXT';
$dataEditNumber = 2;
$html = <<<HTML
<p data-edit="1">TEXT A</p>
<div not-data-edit="2">TEXT C</div>
<div data-edit="2">TEXT B</div>
HTML;

$dom = new DOMDocument; 
$dom->loadHTML('<div>' . $html . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//*[@data-edit=$dataEditNumber]") as $node) {
    $node->nodeValue = $replacement;
}
var_export(substr($dom->saveHTML() ,5, -7));