2012-06-18 40 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