我需要使用Perl中的正则表达式匹配并删除所有标记.我有以下内容:
<\\??(?!p).+?>
但这仍然与结束
注意,这是在xhtml上执行的.
如果你坚持使用正则表达式,这样的东西在大多数情况下都会起作用:
# Remove all HTML except "p" tags $html =~ s{<(?>/?)(?:[^pP]|[pP][^\s>/])[^>]*>}{}g;
说明:
s{ < # opening angled bracket (?>/?) # ratchet past optional / (?: [^pP] # non-p tag | # ...or... [pP][^\s>/] # longer tag that begins with p (e.g.,) ) [^>]* # everything until closing angled bracket > # closing angled bracket }{}gx; # replace with nothing, globally但实际上,为自己省去一些麻烦并改为使用解析器.CPAN有几个适合的模块.下面是一个使用HTML :: TokeParser模块的示例,该模块附带了非常强大的HTML :: Parser CPAN发行版:
use strict; use HTML::TokeParser; my $parser = HTML::TokeParser->new('/some/file.html') or die "Could not open /some/file.html - $!"; while(my $t = $parser->get_token) { # Skip start or end tags that are not "p" tags next if(($t->[0] eq 'S' || $t->[0] eq 'E') && lc $t->[1] ne 'p'); # Print everything else normally (see HTML::TokeParser docs for explanation) if($t->[0] eq 'T') { print $t->[1]; } else { print $t->[-1]; } }HTML :: Parser以文件名,打开文件句柄或字符串的形式接受输入.将上述代码包装在库中并使目标可配置(即,不仅仅是
2> Jörg W Mitta..:在我看来,试图用HTML解析器以外的任何东西解析HTML只是在寻求一个痛苦的世界.HTML是一种非常复杂的语言(这是创建XHTML的主要原因之一,它比HTML简单得多).
例如,这个:
/
是一个完整的,100%格式良好,100%有效的HTML文档.(好吧,它缺少DOCTYPE声明,但除此之外......)
它在语义上等同于
> >
但是,您将不得不处理有效的HTML.当然,您可以设计一个正则表达式来解析它,但是,正如其他人已经建议的那样,使用实际的HTML解析器要简单得多.
3> Xetius..:我想出了这个:
<(?!\/?p(?=>|\s.*>))\/?.*?> x/ < # Match open angle bracket (?! # Negative lookahead (Not matching and not consuming) \/? # 0 or 1 / p # p (?= # Positive lookahead (Matching and not consuming) > # > - No attributes | # or \s # whitespace .* # anything up to > # close angle brackets - with attributes ) # close positive lookahead ) # close negative lookahead # if we have got this far then we don't match # a p tag or closing p tag # with or without attributes \/? # optional close tag symbol (/) .*? # and anything up to > # first closing tag /现在,这将处理带有或不带属性的p标签和关闭p标签,但会匹配pre和类似标签,有或没有属性.
它没有删除属性,但是我的源数据没有将它们放入.我可能会在稍后更改它,但这就足够了.