2010-07-14 63 views
7

因此,我正在編寫一個快速perl腳本,清理一些HTML代碼並通過html - > pdf程序運行它。我想失去儘可能少的信息,所以我想擴展我的textareas以適應當前所有文本。這意味着,在我的情況下,將行數設置爲基於文本框內字符串值的計算值。在Perl正則表達式中嵌入評估

這是我目前使用

$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)/80 })"$2>$3<\/textarea>/gis; 

不幸的是Perl中似乎並沒有被承認我被告知是嵌入內的Perl代碼的語法正則表達式搜索和替換regexs 是否有任何Perl迷都樂意告訴我我做錯了什麼? 問候, 扎克

回答

11

(?{...})模式是一個用於在匹配側執行代碼的實驗性功能,但是您希望在代碼上執行代碼替換方。使用用於該/e正則表達式開關:

#! /usr/bin/perl 

use warnings; 
use strict; 

use POSIX qw/ ceil /; 

while (<DATA>) { 
    s[<textarea rows="(.+?)"(.*?)>(.*?)</textarea>] { 
    my $rows = ceil(length($3)/80); 
    qq[<textarea rows="$rows"$2>$3</textarea>]; 
    }egis; 
    print; 
} 

__DATA__ 
<textarea rows="123" bar="baz">howdy</textarea> 

輸出:

<textarea rows="1" bar="baz">howdy</textarea>
0

我相信你的問題是一個轉義/

如果不是這個問題,那肯定是有問題。

試試這個,注意\/80

$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)\/80 })"$2>$3<\/textarea>/gis; 

這段代碼的基本模式是:

$file =~ s/some_search/some_replace/gis; 

gis是選項,我不得不仰視。我認爲g =全球,i =大小寫不敏感,s =現在沒有任何想法。

+0

perl junkie,我不是。雖然,我想我會努力。 – 2010-07-14 22:37:39

5

您使用嵌入代碼的語法是僅在替代的「匹配」部分(左手有效側)。要在右側嵌入代碼(這是正常的Perl雙引號字符串),你可以這樣做:

$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>} 
      {<textarea rows="@{[ length($3)/80 ]}"$2>$3</textarea>}gis; 

它使用的"some string @{[ embedded_perl_code() ]} more string" Perl的成語。

但是,如果你是一個非常複雜的聲明的工作,可能會更容易把代入「EVAL」模式,它會將替換字符串作爲Perl代碼:

$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>} 
      {'<textarea rows="' . (length($3)/80) . qq{"$2>$3</textarea>}}gise; 

注意,在這兩種示例正則表達式的結構爲s{}{}。這不僅消除了跳過斜槓的必要性,而且還允許您將表達式分散在多行以提高可讀性。

0

首先,您需要在替換文本的表達式中引用/(否則perl會看到一個s ///運算符,後跟數字80等等)。或者你可以使用不同的分隔符;對於複雜的替換,匹配括號是一個好主意。

然後你會遇到主要問題,那就是(?{...})只在模式中可用。替換文本不是模式,它(幾乎)是一個普通的字符串。

相反,有e修改器s///運營商,它可以讓你寫一個替換表達式,而不是替換字符串。

 
$file =~ s(<textarea rows="(.+?)"(.*?)>(.*?)</textarea>) 
      ("<textarea rows=\"" . (length($3)/80) . "\"$2>$3</textarea>")egis; 
0

按照http://perldoc.perl.org/perlrequick.html#Search-and-replace,這可以用「評估修改s///e」來實現,例如,你gis必須對自己的一個額外的e

評估修飾符s /// e圍繞替換字符串包圍eval {...},並將評估結果替換爲匹配的子字符串。一些例子:

# convert percentage to decimal 
$x = "A 39% hit rate"; 
$x =~ s!(\d+)%!$1/100!e;  # $x contains "A 0.39 hit rate"