簡體   English   中英

Perl 在替換本身中進行替換

[英]Perl do substitution in substitution itself

我正在使用 Perl 對 html 片段進行一些正則表達式替換操作。

這就是我匹配所需部分的方式: (class="p_hw"><a href=")(http://[^<>"]*?xxxx\.com\/[^<>"]*[=/])([^<>"]*)(">(?:<b>)?)(.*?)(?=<)

如果該值存在於散列$3 %hw_f http:// entry:// ,或者第一個單詞(或短語) from $5將在%hw_f中存在時使用。 如果所有條件都不匹配,則代碼段將保持不變。

我嘗試了以下方法:

s#(class="p_hw"><a href=")(http://[^<>"]*?xxxx\.com\/[^<>"]*[=/])([^<>"]*)(">(?:<b>)?)(.*?)(?=<)#
        my @n = split(/\,|;/, $5);
    my @m = map {s,^\s+|\s+$,,mgr} @n;
    my $new = $3 =~ s/^\s+|\s+$//mgr;
    my $new2 = $new =~ s/\+/ /mgr;
    exists $hw_f{$new2} ? "$1entry://$new2$4$5" : (exists $hw_f{$m[0]} ? "$1entry://$m[0]$4$5" : "$1$2$3$4$5") #eg;

%hw_f是匹配所有條件的地方。

它給出了以下錯誤:

在連接 (.) 或字符串中使用未初始化的值 $1

我需要在替換中基於$3獲得一個新值,繼續使用該新值。 我怎么能那樣做?

我不會嘗試真正解決您要完成的工作的邏輯,因為這是相當不明智的。 我要做的是提供一些語義和編碼建議。

1:使用 Regexp::Common 和 URI 處理 URL。 編寫自己的正則表達式幾乎不值得。 使用正則表達式解析 HTML 要求您認真了解自己在做什么。 https://metacpan.org/search?q=regexp%3A%3Acommon

2:始終只使用 {} 和 // 來包裝正則表達式。 (99% 的規則)

3:除非表達式是微不足道的,否則總是立即將編號變量復制到有意義命名的 my() 變量中。

4:用后綴foreach就地修改arrays。

5:展開代碼格式,使其具有視覺吸引力。

6:使用 sprintf 進行復雜的變量重組。 它使查看在何處使用什么變量以及用於什么目的變得容易得多。

高溫高壓

#  1                        2                                     3        4           5
s{(class="p_hw"><a href=\")(http://[^<>"]*?xxxx\.com/[^<>"]*[=/])([^<>\"]*)(\">(?:<b>)?)(.*?)(?=<)}{
    my ($m1, $m2, $m3, $m4, $m5) = ($1, $2, $3, $4, $5);
    my @n = split /[,|;]/, $m5;
    s/^\s+|\s+$//mg foreach @n;
    (my $new = $m3) =~ s/^\s+|\s+$//mg;
    (my $new2 = $new) =~ s/\+/ /g;
    exists $hw_f{$new2} ?
        sprintf "%sentry://%s%s%s", $m1, $new2, $m4, $m5 :
        exists $hw_f{$n[0]} ? 
        sprintf "%sentry://%s%s%s", $m1, $n[0], $m4, $m5 :
        "$m1$m2$m3$m4$m5";
}ige;

更新:

while (<DICT>) {
s#(class="p_hw"><a href=")(http://[^<>"]*?wordinfo\.info\/[^<>"]*[=/])([^<>"]*)(">(?:<b>)?)(.*?)(?=<)#
        my $one = $1;
    my $two = $2;
    my $three = $3;
    my $four = $4;
    my $five = $5;
        my @n = split(/\,|;/, $5);
    my @m = map {s,^\s+|\s+$,,mgr} @n;
    my $new = $3 =~ s/^\s+|\s+$//mgr;
    my $new2 = $new =~ s/\+/ /mgr;
    exists $hw_f{$new2} ? $one."entry://$new2$four$five" : (exists $hw_f{$m[0]} ? $one."entry://$m[0]$four$five" : "$one$two$three$four$five") #eg;

    print $FH $_;
}

在提到的評論中將所有正則表達式引擎調用之前的所有捕獲變量分配為@DavidO,它終於起作用了。 謝謝。

從您的帖子來看,您試圖實現的目標並不明顯。 如果您以以下格式描述問題,則更容易理解

- - 例子 - - - - - - - - - - - -

我從 web 頁面中提取了一個帶有<a href="http:\\.......的片段,我想將其轉換/轉換為以下格式<a href="http:\\.......

至少通過這種方式我們知道什么是INPUT以及OUTPUT 的預期。

--- 例子結束 ------------

當您將正則表達式與memory一起應用時,將記住的值存儲在數組或更好的 hash 中會更容易

use strict;
use warnings;

use Data::Dumper;

my %href;

$data = shift;

if( $data =~ /<a href="(\w+):\\\\([\w\d\.]+)\\([\w\d\.]+)\\(.+)">([^<]+)</ ) {
    @href{qw(protocol dns dir rest desc)} = ($1,$2,$3,$4,$5);
    print Dumper(\%href);
} else {
    print "No match found\n";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM