试图让perl正则表达式找到多行和单行HTML注释

时间:2016-03-26 19:47:02

标签: html regex perl

我试图在HTML文件中找到单行和多行注释。我把它剥离了几个例子,还有一些其他的内容只是为了那里有东西。

我在这里阅读了很多条目,但无法得到明确的答案。我正在阅读" slurp"中的HTML文件。模式,并匹配我的模式。此代码现在运行并仅打印第一个匹配。

#!C:\Perl\bin\perl.exe 

BEGIN {  unshift @INC, 'C:\rmhperl'; } 

use warnings;
no warnings 'uninitialized';

chdir 'c:\watts\html'; 

open FILE, "test.html" or print 'error opening file "test.html" ';
my $text = do { local $/; <FILE> };
close(FILE);

if ($text =~ m/(?s)(<!--.*?)(-->\n)/sg) {
    print "1 = $1  2= $2\n";
}

exit;

我在HTML文件中设置了单行和多行注释。我可以得到一个或另一个打印但不是两个(至少在&#34; slurp&#34;模式)。

我告诉我应该能够通过一个正则表达式完成此任务,因此目标是&#34;找到所有HTML注释,无论它们是单行/多行注释&#34;

我构建了正则表达式来查找两者,但只查找第一个匹配项 - 多行注释。

我试图找到一种方法来找到每个匹配,无论是在一行还是多行。我可以找到其中一个,但我不能让他们使用一个正则表达式。

我可以执行非slurp模式,找到<!--标记,然后循环直到看到-->标记,但想知道我是否可以使用单个正则表达式。

我一直在读这个,并试图找到相关的例子。我看不到我错过的东西。这是我用于正则表达式的HTML文件片段:

HTML文件

<!DOCTYPE html>

<script type="text/javascript" src="fadeslideshow.js"></script>
<style>

.divTable {
    display: block;
    width: 100%;
}

.divTableBody, .divTableRow{ clear: both; }

.divTableCell {
    border: 1px solid #999999;
    float: left;
    overflow: hide;
    padding: 2%;
    width: 45%; }

.divTable:after {
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 100px; }
</style>
<style type="text/css">
<!--
a:link {color: #0000ff;}
 a:visited {color: #3563a8;} 
 a:active {color: #000000;}
 a:hover {background-color: #000000;}
 a {text-decoration: none;}
 -->
 </style> 
</head>
    <body class="home">

 <div id="white_back">
<div style="text-align: center">
</div>
<div class="chromestyle" id="chromemenu">
<ul>
<!-- <li><a href="xyz.com">Home</a></li>
 -->
 <li><a href="#" rel="dropmenu0">About Us</a></li>
<li><a href="#" rel="dropmenu5">Publications</a></li>   
</ul>
</div>

<!--1st drop down menu
-->                                                   
<div id="dropmenu0" class="dropmenudiv">
</div>

<!--2nd drop down menu -->
<div id="dropmenu1" class="dropmenudiv">
</div>

1 个答案:

答案 0 :(得分:2)

我认为这是生产代码,在这种情况下,您的经理是一个可怕的人,因为这种做法可能导致难以发现的错误。如果代码仅适用于您自己,但在其他代码上造成这种代码是不公平的,那是可以接受的

关于代码的一些注意事项

  • 在Windows系统上不需要shebang行#!,除非您在那里指定命令行选项,否则实际上什么都不做。最好放弃它

  • 始终 use strictuse warnings 'all',修复错误,而不是使用no warnings 'uninitialized'

  • 停用警告
  • BEGIN { unshift @INC, 'C:\rmhperl' }最好是use lib 'C:\rmhperl',但在这种情况下您不使用库,因此无效

  • 您应该使用 lexical 文件句柄与三参数形式的open

  • 正则表达式模式中不需要(?s)以及/s修饰符。除非你正在做一些花哨的事情,比如只为模式的一部分启用选项(你不是),如果你使用修饰符/s

  • ,人们会更好地理解你

您只发现一条评论的原因是您只需要一条评论。在标量上下文中,全局正则表达式模式匹配将一次迭代目标字符串中的所有匹配。你只调用一次,所以它只找到第一个。您可以使用while代替if

来解决此问题

我确保开场<--后跟>->,这会形成非法的HTML评论,从而在某种程度上改善了您的正则表达式模式。在结束-->之后,可能还有可选空间,因此我允许这样做。并且你在评论结束后坚持使用换行符可能不存在,所以我已经删除了

此代码似乎适用于您的数据

use strict;
use warnings 'all';

my $text = do {
    open my $fh, '<', 'test.html' or print qq{Unable to open file "test.html" for input: $!};
    local $/;
    <$fh>;
};

while ( $text =~ /(<!--(?!-?>).*?--\s*>)/sg ) {
    my $comment = $1;
    print $comment, "\n";
}

输出

<!--
a:link {color: #0000ff;}
 a:visited {color: #3563a8;} 
 a:active {color: #000000;}
 a:hover {background-color: #000000;}
 a {text-decoration: none;}
 -->
<!-- <li><a href="xyz.com">Home</a></li>
 -->
<!--1st drop down menu
-->
<!--2nd drop down menu -->