如何停止。+在字符的第一个实例而不是在perl中使用正则表达式的最后一个?

时间:2010-12-21 03:29:00

标签: regex perl

我想替换:

'''<font size="3"><font color="blue"> SUMMER/WINTER CONFIGURATION FILES</font></font>'''

使用:

='''<font color="blue"> SUMMER/WINTER CONFIGURATION FILES</font>'''=

现在我现有的代码是:

$html =~ s/\n(.+)<font size=\".+?\">(.+)<\/font>(.+)\n/\n=$1$2$3=\n/gm

然而,最终结果如下:

=''' SUMMER/WINTER CONFIGURATION FILES</font>'''=

现在我可以看到发生了什么,它匹配<font size ="..... all the way up to the end of the <font colour blue">这不是我想要的,我希望它停在第一个而不是最后一个实例,我想这就是把标记放在那里的东西,但是我已经尝试了。+。+?。*和。*?每次都有相同的结果。

任何人都有任何想法我做错了什么?

3 个答案:

答案 0 :(得分:8)

在所有地方写下.+? ,使每场比赛都不贪婪。

$html =~ s/\n(.+?)<font size=\".+?\">(.+?)<\/font>(.+?)\n/\n=$1$2$3=\n/gm
                ^                ^      ^            ^

还要尽量避免使用正则表达式来解析HTML。如果可能,请使用HTML解析器。

答案 1 :(得分:7)

您可以将.+更改为[^"]+(而不是“匹配任何内容”,“匹配任何不属于"的内容”......

答案 2 :(得分:4)

正如马克所说,只需使用CPAN即可。

#!/usr/bin/env perl

use strict; use warnings;
use HTML::TreeBuilder;

my $s = q{<font size="3"><font color="blue"> SUMMER/WINTER CONFIGURATION FILES</font></font>};

my $tree = HTML::TreeBuilder->new;
$tree->parse( $s ); 
print $tree->find_by_attribute( color => 'blue' )->as_HTML;

# => <font color="blue"> SUMMER/WINTER CONFIGURATION FILES</font>

这适用于您的特定情况:

#!/usr/bin/env perl

use strict; use warnings;

my $s = q{<font size="3"><font color="blue"> SUMMER/WINTER CONFIGURATION FILES</font></font>};

print $s =~ m{
                 < .+? >
                 (.+)?
                 </.+? >                
             }mx;

# => <font color="blue"> SUMMER/WINTER CONFIGURATION FILES</font>