如何使用正则表达式从字符串中删除其他标记?

时间:2011-03-01 18:38:36

标签: php preg-replace domdocument

我使用php DOMDocument替换节点然后重写页面。写回的HTML是纯文本(不是HTML),所以我必须像这样转换它:

$content = files::readFile($data['page_path']);
$content = str_replace('&lt;', '<', $content);
$content = str_replace('&gt;', '>', $content);

if (!@fwrite($handle, $content))
{
    print 'Failed to replace entities';
    return FALSE;
}

这使得HTML正常,但由于一些奇怪的原因,它增加了额外的&lt; / html&gt;标记到文档的底部,在违规后用一些附加数据&lt; / html&gt;标签。我完全失去了原因。

无论如何,我想过使用:

$content = preg_replace('#\<\/head\>*(:alphanum:)#', '</html>', $content);

删除它,但这与我想象的方式不符。

请帮忙!

测试示例:

$html = '
   <div id="footer">
       <div class="wrap">
           <strong class="logo"><a href="#">College</a></strong>
           <ul><li><a href="#">Emergencies</a></li>
               <li><a href="#">Contact</a></li>
               <li><a href="#">Copyright</a></li>
               <li><a href="#">Terms of Use</a></li>
               <li><a href="#">Member of The Colleges</a></li>
           </ul><p>© 2010 College</p>
       </div>
   </div>
</body></html>
li>
               <li><a href="#">Contact</a></li>
               <li><a href="#">Copyright</a></li>
               <li><a href="#">Terms of Use</a></li>
               <li><a href="#">Member of The Colleges</a></li>
           </ul><p>© 2010 College</p>
       </div>
   </div>
</body></html>';

preg_match("#</head>.*#si", $html, $matches);
var_dump($matches);

3 个答案:

答案 0 :(得分:0)

您的代码:

$content = preg_replace('#\<\/head\>*(:alphanum:)#', '</html>', $content);

这不起作用的原因是因为:alphanum:在PREG样式的正则表达式中不是有效的语法。 PHP的ereg风格的正则表达式函数允许这样的字符类,但这些函数已被弃用,所以你应该坚持使用PREG。

解决方案是用正确的PREG语法替换:alphanum:

如果是:alphanum:,则正确的语法为[0-9a-zA-Z]

对于任何数字字符,还有\d等快捷方式,可以用来代替0-9。有关这些内容的详情,请参阅http://www.regular-expressions.info/reference.html

[编辑]

所以现在你有:

$content = preg_replace('#\<\/head\>*([0-9a-zA-Z])#', '</html>', $content);

正如你所说,这仍然无法奏效,但至少会解决明显的问题。

第一个问题:你在正则表达式中有“”,但是你似乎要求在“”之后更换所有内容 - 这是一个错字吗?

第二点:正则表达式[0-9a-zA-Z]只匹配一个单个字符。要匹配多个字符,您需要在+之后添加*[0-9a-zA-Z]。加号表示您要匹配[0-9a-zA-Z]中的一个或多个,而星号表示零个或多个出现。

第三点:您在问题中引用的代码不仅包括字母数字字符。它是HTML,因此它包括尖括号,#-symbols,甚至是版权符号。显然[0-9a-zA-Z]将不会匹配其中任何一个(:alphanum:也不会使用ereg语法)。

您可以将代码中可能出现的所有字符添加到正则表达式中,以制作类似[0-9a-zA-Z<>#]的内容,但这可能不实用。更好的想法是匹配任何角色,而不是专门寻找字母数字。要匹配任何字符,您将使用点(.),因此您的正则表达式看起来更像这样:

$content = preg_replace('#</html>.+#', '</html>', $content);

希望有所帮助。

答案 1 :(得分:0)

我不确定字母数字字符究竟是如何与问题相符的,但我怀疑你想要字母数字后的*通配符以匹配任意数量的字符:

$content = preg_replace('#</head>[\da-z]*#i', '</html>', $content);

事实上,我想知道您是否甚至想要匹配</head>标记之后的所有内容,在这种情况下,这可能对您有用:

$content = preg_replace('#</head>.*#si', '</html>', $content);

编辑:现在您已添加示例文字,我看到您有2个</html>标记。怎么样:

$content = preg_replace('#</html>.*#si', '</html>', $content); 

答案 2 :(得分:0)

我遇到的问题已经解决: 我想出了我在可重用内容中遇到的奇怪错误!我在使用模式'r +'时使用PHP的函数fwrite()时发现了这个问题。如果您在php.net/fopen上看到此函数的文档,您将看到r +执行以下操作:打开以进行读写;将文件指针放在文件的开头。我天真地认为这意味着由于指针在开头,它会覆盖整个文件内容。不,实际上这不是事实。如果你想要这种效果,你必须使用模式'w',它执行以下操作:打开只写;将文件指针放在文件的开头,并将文件截断为零长度。如果该文件不存在,请尝试创建它。