1

我正在尝试确定是否可以使用 preg_replace 执行以下操作,如果可以,您可以向我展示一个带有注释的示例,以便我从中学习。

我有一些看起来像这样的 html 代码:

<ul class="sub-menu">
<li id="menu-item-99" class="menu-item"><a href="/clients-login-english/">Login**</a></li>
<li id="menu-item-100" class="menu-item"><a href="/clients-create-account-english/">Create Account%%</a></li>
</ul>

我想要做的是找到“代码”的位置,在这种情况下是“* *”或“%%”,并删除从前面的 < li 开始并以下一个 < /li > 结束的文本。因此,如果我对此使用 preg_replace 并正在寻找“**”,它最终会看起来像:

<ul class="sub-menu">

<li id="menu-item-100" class="menu-item"><a href="/clients-create-account-english/">Create Account%%</a></li>
</ul>

我最初的想法是使用蛮力方法并使用stripos找到“**”,然后从那里向后循环找到<li,然后在它之后寻找</li>并重建字符串减去这部分但是似乎必须有一个更简单的方法。

4

1 回答 1

1

请理解,使用正则表达式解析 HTML 很容易出错。请避免使用它,除非您非常确定要获得的 HTML 文本。

话虽如此,这是一个基于正则表达式的代码来做你想做的事:

$html = <<< EOF
<ul class="sub-menu">
<li id="menu-item-99" class="menu-item"><a href="/clients-login-english/">Login**</a></li>
<li id="menu-item-100" class="menu-item"><a href="/clients-create-account-english/">Create Account%%</a></li>
</ul>
EOF;
echo preg_replace('#<li\s.*?<a[^\*]+\*\*</a></li>#s', '', $html). "\n";

编辑:这是实现上述目标的基于 DOM 的(和推荐的)方法:

$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html); // loads your html
$xpath = new DOMXPath($doc);
$nlist = $xpath->query("//ul[@class='sub-menu']/li");

$nodesToDelete = array();
$numnodes = $nlist->length;
for($i=0; $i < $numnodes; $i++) {
   $node = $nlist->item($i);
   $val = $node->nodeValue;
   if (strstr($val, '**'))
      $nodesToDelete[] = $node;
}

foreach($nodesToDelete as $node)
   $node->parentNode->removeChild($node);

$newHTML =  $doc->saveHTML();
echo $newHTML;
于 2012-04-27T14:11:45.017 回答