我对正则表达式不是很熟练,但正在学习。
我想通过类名删除一些HTML标记。目前为止,我的代码如下:
<div class="footer".*?>(.*?)</div>
第一个 .*? 是因为它可能包含其他属性,第二个是因为它可能包含其他HTML内容。
我做错了什么?我尝试了很多设置但都没有成功。
更新
DIV内部可以包含多行文本,并且我正在使用Perl正则表达式进行操作。
我对正则表达式不是很熟练,但正在学习。
我想通过类名删除一些HTML标记。目前为止,我的代码如下:
<div class="footer".*?>(.*?)</div>
第一个 .*? 是因为它可能包含其他属性,第二个是因为它可能包含其他HTML内容。
我做错了什么?我尝试了很多设置但都没有成功。
DIV内部可以包含多行文本,并且我正在使用Perl正则表达式进行操作。
正如其他人所说,使用正则表达式处理HTML非常棘手,DOM方法可能更好。例如:
use HTML::TreeBuilder::XPath;
my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse_file( 'yourdocument.html' );
for my $node ( $tree->findnodes( '//*[@class="footer"]' ) ) {
$node->replace_with_content; # delete element, but not the children
}
print $tree->as_HTML;
在 div 标签中,您还需要允许其他事项在类之前。
<div[^>]*class="footer"[^>]*>(.*?)</div>
此外,要不区分大小写地进行操作。您可能需要转义引号或关闭标签中的斜杠等字符。您正在执行什么上下文操作?另外请注意,使用正则表达式解析HTML可能会非常复杂,这取决于输入情况。下面的答案提出了一个很好的观点-假设您有以下结构:
<div>
<div class="footer">
<div>Hi!</div>
</div>
</div>
试图为此构建正则表达式是一种灾难性的做法。你最好将文档加载到DOM中,并对其进行操作。
伪代码应该与XML::DOM密切相关:
document = //load document
divs = document.getElementsByTagName("div");
for(div in divs) {
if(div.getAttributes["class"] == "footer") {
parent = div.getParent();
for(child in div.getChildren()) {
// filter attribute types?
parent.insertBefore(div, child);
}
parent.removeChild(div);
}
}
<div[^>]*class="footer"[^>]*>(.*?)</div>
对我来说有效,但需要在特殊字符前使用反斜杠
<div[^>]*class=\"footer\"[^>]*>(.*?)<\/div>
/s
修饰符,否则点号将无法匹配换行符。部分取决于您使用的正则表达式引擎 - 使用的语言等。但一个可能性是您需要转义引号和/或斜杠。您还可以将其设置为不区分大小写。
<div class=\"footer\".*?>(.*?)<\/div>
试试这个:
<([^\s]+).*?class="footer".*?>([.\n]*?)</([^\s]+)>
你最大的问题可能会是嵌套标签。例如:
<div class="footer"><b></b></div>
</b>
,留下</div>
悬挂在末尾。你需要假设你要查找的标签没有嵌套元素,或者你需要使用一些从HTML到DOM的解析器和XPath查询来删除整个子树。这将会很棘手,因为正则表达式的贪婪性,(请注意我的例子可能是特定于perl的,但我知道贪婪性是REs的一个普遍问题。)第二个.*?
将尽可能匹配到</div>
之前的所有内容,所以如果你有以下内容:
<div class="SomethingElse"><div class="footer"> stuff </div></div>
表达式将匹配:
<div class="footer"> stuff </div></div>
这不太可能是你想要的。
为什么不使用 <div class="footer".*?</div>
呢?我也不是正则表达式专家,但我认为你不需要指定最后一个括号来匹配开放的 div 标签。