7

我不太擅长正则表达式,但我正在学习。

我想通过类名删除一些 html 标记。这是我到目前为止所拥有的:

<div class="footer".*?>(.*?)</div>

首先 。*?是因为它可能包含其他属性,第二个是它可能包含其他 html 内容。

我究竟做错了什么?我已经尝试了很多设置但没有成功。

更新

在 DIV 内它可以包含多行,我正在使用 Perl 正则表达式。

4

8 回答 8

17

正如其他人所说,使用正则表达式处理 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;
于 2008-10-22T16:52:25.860 回答
15

您还需要在 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);
    }
}


这是一个 perl 库HTML::DOM和另一个XML::DOM
.NET 具有用于处理 dom 解析的内置库。

于 2008-10-22T16:32:54.057 回答
1

在 Perl 中,您需要/s修饰符,否则点将不匹配换行符。

也就是说,使用适当的 HTML 或 XML 解析器来删除 HTML 文件中不需要的部分更为合适。

于 2008-10-22T16:37:05.437 回答
1
<div[^>]*class="footer"[^>]*>(.*?)</div>

为我工作,但需要在特殊字符之前使用反斜杠

<div[^>]*class=\"footer\"[^>]*>(.*?)<\/div>
于 2009-02-05T04:07:42.717 回答
0

部分取决于您使用的确切正则表达式引擎 - 哪种语言等。但一种可能性是您需要转义引号和/或正斜杠。您可能还想让它不区分大小写。

<div class=\"footer\".*?>(.*?)<\/div>

否则,请说出您使用的语言/平台 - .NET、java、perl ...

于 2008-10-22T16:31:06.247 回答
0

试试这个:

<([^\s]+).*?class="footer".*?>([.\n]*?)</([^\s]+)>

您最大的问题将是嵌套标签。例如:

<div class="footer"><b></b></div>

给出的正则表达式将通过 匹配所有内容</b>,最后留下</div>悬空。您将不得不假设您要查找的标记没有嵌套元素,或者您将需要使用某种从 HTML 到 DOM 的解析器和 XPath 查询来删除整个子树。

于 2008-10-22T16:34:19.750 回答
0

由于正则表达式的贪婪,这将很棘手,(请注意,我的示例可能特定于 perl,但我知道贪婪是 RE 的普遍问题。)第二个.*?将在 之前尽可能匹配</div>,所以如果你有以下几点:

<div class="SomethingElse"><div class="footer"> stuff </div></div>

表达式将匹配:

<div class="footer"> stuff </div></div>

这不太可能是您想要的。

于 2008-10-22T16:37:26.327 回答
-3

为什么<div class="footer".*?</div> 我也不是正则表达式大师,但我认为您不需要为打开的 div 标签指定最后一个括号

于 2008-10-22T16:31:47.523 回答