匹配第一次出现的字符串

时间:2013-12-13 08:42:08

标签: html regex perl

我有一个需要删除代码内容的HTML代码。他们的人数约为30人。它存在于HTML代码中的各个位置,如

 <A class=tooltiplink href="javascript:void;" style="color:#000000"><img src="images/footnote.jpg" border="0"><SPAN style="margin:0 0 0 0px;"> unwanted info 4:6 </SPAN></A> 
<b>Hello </b>  
<A class=tooltiplink href="javascript:void;" style="color:#000000"><img src="images/footnote.jpg" border="0"><SPAN style="margin:0 0 0 0px;"> unwanted info 4:6 </SPAN>
</A><b>World</b>
<A class=tooltiplink href="javascript:void;" style="color:#000000"><img src="images/footnote.jpg" border="0"><SPAN style="margin:0 0 0 0px;"> unwanted info 4:6 </SPAN></A>

所需的输出: Hello World

当我尝试将代码内容移除为$_=~s/A(.+)?\/A//gs;时。它还会占用最后一个标签内的有用信息。去除g也具有相同的效果。如何仅删除标记内容而不使用第一个和最后一个匹配,并删除有用信息。

2 个答案:

答案 0 :(得分:2)

我认为虽然你可以用正则表达式做到这一点,但这不是最好的方法。 TreeBuilder和某些XPath之类的内容会为您提供更易于维护的解决方案。

将HTML加载到树结构中后,所需的XPath可能非常简单:

my $tree= HTML::TreeBuilder::XPath->new;
$tree->parse_file( "mypage.html");

my @nodes = $tree->find_nodes( '//b' );

答案 1 :(得分:1)

你的问题是正则表达式是贪婪的,即它匹配最长的匹配子字符串(从最后一个A到最后一个/ A)。试试+运算符的非贪婪版本:

$_=~s/A(.+?)?\/A//gs;

$_=~s/A(.*?)\/A//gs;

顺便说一下,&lt;&gt;在哪里?正则表达式中的字符?您不想找到<A>而不仅仅是A吗?

你可能意味着

$_=~s/\<A\>.*?\<\/A\>//gs;

见这里:How can I write a regex which matches non greedy?

评论:使用正则表达式解析HTML不是一个好主意,因为太多可能出错(例如,使用上述方法,您找不到带有空格的标记)。除非练习是针对特殊问题的快速解决方案,否则请使用HTML解析器!