2012-06-18 43 views
2

这里是一个Perl代码虽小,但功能片段:的Perl负前瞻

my $content = qq{<img src='h}; 
if ($content =~ m{src=(?!('*)http://)}) { 
    print "Match '$1'\n"; 
} 
else { 
    print "No match\n"; 
} 

它打印

Match ''' 

这是正则表达式('*)负面看,里面超前确实已被抓获,并包含”。

但是如果我有

my $content = qq{<img src='i}; 

代替在第一行脚本打印

Match '' 

意思是“尚未尽管整个正则表达式匹配的捕获。

任何人都可以解释有什么区别,我怎样才能使它'总是被捕获(这当然是一个真实案例的简化)。

在此先感谢

附录

现在,这是raina77ow整个故事。这个想法是替换img标签中的src属性的内容。以下规则适用:

  1. 如果内容以'必须以'结尾'开始。
  2. 如果内容以“它必须以...结尾”开头。
  3. 内容可以不加引号。
  4. 如果内容(在可能的引用之后)以http://开始,它应该保持不变,否则必须保留URL(图像文件名)的最后一个组件,并且必须用smth代替前一部分。

本来我想用下面的正则表达式(这实际上是你的建议相同)

$content =~ s{<\s*img\s+(.*?)src\s*=\s*(["']*)(?!http://).*?([^/"']+)\2(\s+[^>]+)*>} 
      {'<img ' . $1 . 'src="' . 'SMTH' . $3 . '"' . $4 . '>'}sgie; 

,但由于某种原因,它

[IMG SRC匹配字符串= 'http://qq.com/img.gif'/ ]

(尖括号被正方形取代)。

虽然它不应该因为后面跟着http://。使用

$content =~ s{<\s*img\s+(.*?)src\s*=\s*(["'])*(?!http://).*?([^/"']+)\2(\s+[^>]+)*>} 
      {'<img ' . $1 . 'src="' . 'SMTH' . $3 . '"' . $4 . '>'}sgie; 

也不合适,因为在这种情况下\ 2不会匹配空字符串。

无法解决,我决定寻找一些解决方法。唉...

+1

首先,我会建议用HTML解析器,而不是用正则表达式解析HTML。 '$ content'中缺少'http://'部分,所以它不会匹配。 –

+0

我重申使用一个真正的HTTP解析器。正则表达式不适合处理HTML。我推荐[HTML :: TreeBuilder :: XPath](https://metacpan.org/module/HTML::TreeBuilder::XPath) – Quentin

+0

谢谢你的建议,但是这并不能回答原来的问题。然后,正如我指出的那样,正则表达式确实匹配。问题是捕捉括号不被捕获。 – user1463382

回答

1

嗯,这是很容易解决这个问题:

my $content = qq{<img src='h}; 
if ($content =~ m{src=('*)(?!http://)}) { 
    print "Match '$1'\n"; 
} 
else { 
    print "No match\n"; 
} 

但解释你所描述的错误(我认为这是真正的Perl的正则表达式引擎中的错误 - 为什么('*)'h'i案件匹配不同? )是另一回事。 )

UPDATE:原谅我提交给邪神的方式,但是这个代码可以做你的要求为:

sub correct { # just an example 
    my $orig = shift; 
    $orig =~ s/\.gif$/\.jpg/; 
    return $orig; 
} 

my $img = "<img src='http://localhost.com/pic.gif' />"; 
$img =~ s{ 
    (< \s* img \s+ src \s* = \s*) 
    (["']?) 
    ([^ '">]+) 
    \2 
}{ 
    $1 . $2 . (substr($3, 0, 7) eq 'http://' ? $3 : correct $3) . $2 
}xe; 

print $img; 

尽管如此,那些谁说,这是更好地使用HTML解析器,任何的他们有最大的线索,我想。 )

+0

因为这会导致我们误入歧途,所以这种解决方案不适合。如果你能告诉我这个故事,我会很高兴。 – user1463382

+0

然后请描述为什么这个解决方案不适合,不是吗?无论如何,这一点并不在代码中,而是决定使用_two_'查找'而不是单个查询。 – raina77ow

+0

好的,这是整个故事。这个想法是取代img标签的src atrribute的内容。规则应该是: – user1463382

4

从应用问题四大规则与一个强大的HTML解析器/库:

use strictures; 
use URI qw(); 
use Web::Query qw(); 
my $w = Web::Query->new_from_html(<<'HTML'); 
<html><head></head><body> 
<img src='http://example.com'> 
<img src="http://example.com"> 
<img src=http://example.com> 
<img src='foo/bar/baz.png'> 
<img src="foo/bar/baz.png"> 
<img src=foo/bar/baz.png> 
</body></html> 
HTML 

$w->find('img')->each(sub { 
    my (undef, $img) = @_; 
    my $u = URI->new($img->attr('src')); 
    unless ($u->scheme) { # skip absolute URIs 
     $u->path_segments('SMTH', ($u->path_segments)[-1]); 
     $img->attr('src', $u); 
    } 
}); 
print $w->html; 
+0

有勇气与克苏鲁作战。 ) – raina77ow