我想在字符串中找到尚未在<pre>
标记内的评论标记,并将其包装在<pre>
标记中。
似乎没有办法找到&#39;使用PHP DOM的评论。
我已经使用正则表达式进行了一些处理,但是我非常不熟悉(尚未掌握或真正理解)展望未来并在正则表达式中看后面。
例如,我可能有以下代码;
<!-- Comment 1 -->
<pre>
<div class="some_html"></div>
<!-- Comment 2 -->
</pre>
我想在<pre>
代码中包含评论1,但显然不是评论2,因为它已经位于<pre>
。
这通常如何在RegEx中完成?
这是我对负面看法的理解,以及我对其中的一种尝试,我显然做了一些非常错误的事情!
(?<!<pre>.*?)<!--.*-->(?!.*?</pre>)
答案 0 :(得分:2)
如果您计划重新使用此代码,则应该使用DOM解析器。当呈现真实世界的HTML时,每个正则表达式方法都会很快失败。
话虽如此,这是你能做的(但不应该,见上文):
首先,确定评论,例如使用
<!-- (?:(?!-->).)*-->
负向预测块确保。*不会用完注释块。
现在,您需要确定此评论是否在<pre>
块内。这里的关键观察是,每个评论之后的<pre>
或</pre>
元素都是偶数个。
因此,请仔细检查文本的其余部分,并始终成对<pre>
,并检查是否到达最后。
这看起来像
(?=(?:(?!</?pre>).)*(?:</?pre>(?:(?!</?pre>).)*</?pre>(?:(?!</?pre>).)*)*$)
所以,这将是
<!-- (?:(?!-->).)*-->(?=(?:(?!</?pre>).)*(?:</?pre>(?:(?!</?pre>).)*</?pre>(?:(?!</?pre>).)*)*$)
只写代码的欢呼=)
此表达式的突出构建块是(?:(?!</?pre>).)
,它匹配的每个字符都不是<pre>
或</pre>
序列的起始括号。
允许<pre>
上的属性和正确的转义留给读者练习。请在RegExr处查看此操作。
答案 1 :(得分:1)
似乎没有办法使用PHP DOM“查找”评论。
当然你可以......使用PHP Simple HTML DOM Parser检查此代码:
<?php
$text = '<!-- Comment 1 -->
<pre>
<div class="some_html"></div>
<!-- Comment 2 -->
</pre>';
echo "<div>Original Text: <xmp>$text</xmp></div>";
$html = str_get_html($text);
$comments = $html->find('comment');
// if find exists
if ($comments) {
echo '<br>Find function found '. count($comments) . ' results: ';
foreach($comments as $key=>$com){
echo '<br>'.$key . ': ' . $com->tag . ' wich contains = <xmp>' . $com->innertext . '</xmp>';
}
}
else
echo "Find() fails !";
?>
$com->innertext
会为您提供<!-- Comment 1 -->
...
您现在只需按照自己的意愿清洁它们。例如,使用<!--\s*(.*)\s*-->
...尝试HERE
只是关于lookbehind的注释,它必须有固定宽度,因此你不能使用重复*+
或可选项?
坏消息是大多数正则表达式都不允许你在lookbehind中使用任何正则表达式,因为它们不能向后应用正则表达式。因此,正则表达式引擎需要能够在检查lookbehind之前找出退回的步骤数。
因此,许多正则表达式,包括Perl和Python使用的那些,只允许固定长度的字符串。您可以使用任何可以预先确定匹配长度的正则表达式。这意味着您可以使用文字文本和字符类。您不能使用重复或可选项。您可以使用交替,但仅当交替中的所有选项具有相同的长度时才会使用。
答案 2 :(得分:0)
Xpath是你的朋友:
$xpath = new DOMXpath($doc);
foreach($xpath->query('//comment()[not(ancestor::pre)]') as $comment){
$pre = $doc->createElement("pre");
$comment->parentNode->insertBefore($pre, $comment);
$pre->appendChild($comment);
}
答案 3 :(得分:0)
它很容易,使用一个称为堆栈计数器的原则,基本上你计算<pre>
标签的数量和</pre>
标签的数量,直到HTML代码中的点为止细分市场。
如果更多 <pre>
而不是</pre>
- 这意味着“<pre>..--you are here--..</pre>
”。
在这种情况下,只需返回比赛,未经修改 - 就这么简单。