2012-09-10 61 views
1

我試圖用一個字符串替換whitespaces,並將其與正則表達式匹配。Perl正則表達式:嘗試修改只讀值

my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid"; 

if ($string =~ m!(Season\s\d+\sEpisode\s\d+)!){ 

    $1 =~ s!\s+!!g; 

    say $1; 

} 

現在,當我運行上面的代碼,我得到Modification of a read-only value attempted。現在,如果我將$1的值存儲在一個變量中,而不是嘗試對該變量執行替換,則它可以正常工作。

那麼,有沒有什麼方法可以在不創建新的臨時變量的情況下執行替換。

PS:有人能告訴我怎麼寫上面的代碼作爲一個班輪因爲我無法:)

+0

我使用'Perl 5.14'。 – RanRag

+0

你期望什麼結果?只是「Season1Episode1」沒有其餘的字符串? –

+0

難道你不能只說's!\ s + !! g;'? – Qnan

回答

6

不要亂用特殊變量,只是捕捉你想要的數據,而建築業總產值你自己。

$string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid"; 
if ($string =~ m!Season\s(\d+)\sEpisode\s(\d+)!){ 
    say("Season$1Episode$2"); 
} 
+0

尼斯沒有想到這一點。 – RanRag

-1

你可以試試這個:

perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' file 

測試如下:

XXX> cat temp 
watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid 
XXX> perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' temp 
XXX> cat temp 
watchdownloadBuffytheVampireSlayerSeason1Episode1GorillavidXXX> 
+0

當解決方案正確時,爲什麼會出現downvote。如您所見,修改是以行內方式完成的。 – Vijay

3

它看起來像你想的原始字符串

內壓縮Season 1 Episode 1Season1Episode1這可能是使用@-和0方便地完成一起substr呼叫作爲一個左

這個程序一起給出了這個概念

use strict; 
use warnings; 

my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid"; 

if ($string =~ /Season\s+\d+\s+Episode\s+\d+/) { 

    substr($string, $-[0], $+[0] - $-[0]) =~ s/\s+//g; 
    print $string; 
} 

輸出

watch download Buffy the Vampire Slayer Season1Episode1 Gorillavid 

爲什麼你想在一個寫這個你不說線,但如果你必須那麼這將爲你做

perl -pe '/Season\s*\d+\s*Episode\s*\d+/ and substr($_, $-[0], $+[0] - $-[0]) =~ s/\s+//g' myfile 
+0

哪裏可以找到'@ - 和@ +'的相關文檔。 – RanRag

+1

@RanRag:看看[這裏](http://perldoc.perl.org/perlvar.html)並搜索'@ LAST_MATCH_START'和'@ LAST_MATCH_END' – Borodin

+0

@RanRag'perldoc -v @ -'(使用適當的引用避免殼體內插。) – TLP

1
$string =~ s{(?<=Season)\s*(\d+)\s*(Episode)\s*(\d+)}{$1$3$2}; 
1

如果使用腳本後for循環創建的$_本地實例,您可以用打印(使用逗號)來實現匹配的印前處理鏈的替代。

請注意,使用全局/g選項時不需要括號。另請注意,這會使if語句冗餘,因爲任何不匹配都會將空列表返回到for循環。

perl -nlwe 's/\s+//g, print for /Season\s+\d+\s+Episode\s+\d+/g;' yourfile.txt 

在你的腳本中,它看起來像這樣。請注意,if語句被替換爲for循環。

for ($string =~ /Season\s+\d+\s+Episode\s+\d+/g) { 
    s/\s+//g; # implies $_ =~ s/\s+//g 
    say;  # implies say $_ 

} 

這主要是爲了展示一襯墊。您可以插入一個詞彙變量,而不是使用$_,例如如果您想增加可讀性,請使用for my $match (...)