PHP preg_replace用法与强力方法

时间:2012-04-27 13:50:27

标签: php preg-replace

我正在尝试确定是否可以使用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>

我想要做的是找到&#34;代码&#34;的位置,在这种情况下是&#34; * *&#34;或者&#34; %%&#34;并删除前面开头的文本&lt; li并以下一个&lt; / li&gt;。所以如果我在这上面使用preg_replace并且正在寻找&#34; **&#34;它最终会像:

<ul class="sub-menu">

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

我最初的想法是使用蛮力方法并使用stripos来找到&#34; **&#34;然后从那里向后循环以找到&lt; li然后寻找&lt; / li&gt;在它之后并重建字符串减去此部分,但似乎必须有一个更简单的方法。

1 个答案:

答案 0 :(得分: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;