2008-09-25 69 views
1

假設我想寫一個正則表達式,將所有<abc><def><ghi>標籤更改爲<xyz>標籤..我也想將其結束標籤更改爲</xyz>。這似乎是一個合理的正則表達式(忽略反引號; StackOverflow上具有與低於跡象,如果我不把他們麻煩):如何使此「使用未初始化的值」警告消失?

`s!<(/)?(abc|def|ghi)>!<${1}xyz>!g;` 

和它的作品了。唯一的問題是,對於打開標籤,可選的$ 1變量被賦予undef,所以我得到一個「Use of uninitialized value ...」警告。

什麼是解決這個問題的優雅方法?我寧願不要將它分成兩個單獨的正則表達式,一個用於打開標籤,另一個用於關閉標籤,因爲那樣就有兩個需要維護的taglist副本,而不僅僅是一個。

編輯:我知道我可以在代碼的這個區域關閉警告,但我不認爲這是「優雅」。

+0

對於小於號,請嘗試使用<。我知道,這是愚蠢的,因爲它在沒有它的情況下在預覽中看起來是正確的,但是我就是這麼想的。 – 2008-09-25 21:31:55

回答

10

移動捕獲括號內的問號。這樣$ 1總是被定義的,但可能是一個零長度的字符串。

1

你可以讓你的第一個匹配成爲(< /?),並在「替換」一方去掉硬編碼的<。那麼$ 1將始終具有「<」或「< /」。解決警告問題可能有更優雅的解決方案,但這個應該解決實際問題。

1

這裏有一種方法:

s!<(/?)(abc|def|ghi)>!<$1xyz>!g; 

更新:刪除了有關使用(?:pattern)無關的評論。

+0

但我*要*想要捕捉。 – raldi 2008-09-25 21:30:56

+0

我誤讀了。我會修復它... – jmcnamara 2008-09-25 21:54:06

-1

添加

no warnings 'uninitialized'; 

s!<(/)?(abc|def|ghi)>! join '', '<', ${1}||'', 'xyz>' !ge; 
2

如何:

`s!(</?)(abc|def|ghi)>!${1}xyz>!g;` 
0

要在兩種情況下,正則表達式捕獲$ 1,嘗試:

s!<(/|)?(abc|def|ghi)>!<${1}xyz>!g; 
    ^
     note the pipe symbol, meaning '/' or '' 

因爲''會捕獲'<'和'abc>'之間的'','','<'和'abc>'之間的捕獲'/'。

1

s!<(/?)(abc|def|ghi)>!<${1}xyz>!g;

唯一不同的是改變 「(/)?」至 」(/?)」。您已經確定了幾個功能解決方案。我認爲,這個有你要求的優雅。

0

我寧願不使這種分成兩個單獨的 regexs,一個打開的標籤 ,另一個用於關閉標籤,因爲 然後有需要維持

的 標記列表的兩個副本

爲什麼?將您的標籤列表放入一個變量中,並根據您的喜好將該變量插入到儘可能多的正則表達式中。我認爲這甚至只有一個正則表達式,因爲它更復雜的正則表達式(以及哪個正則表達式並不複雜?)。

0

要小心儘可能多的HTML是有點難,那麼它看起來乍一看。例如,是否要將「< abc foo ='bar'>」「更改爲」< xyz foo ='bar'>「?你的正則表達式不會。你想改變「< img alt ='< abc>'>」?正則表達式將會。相反,你可能想要做這樣的事情:

use HTML::TreeBuilder; 
my $tree=HTML::TreeBuilder->new_from_content("<abc>asdf</abc>"); 
for my $tag (qw<abc def ghi>) { 
    for my $elem ($tree->look_down(_tag => $tag)) { 
    $elem->tag('xyz'); 
    } 
} 
print $tree->as_HTML; 

這讓你無需自己動手解析HTML。

相關問題