如何使此“使用未初始化的值”警告消失?

如何使此“使用未初始化的值”警告消失?

问题描述:

假设我想写一个正则表达式,将所有<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

移动捕获括号内的问号。这样$ 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

添加

no warnings 'uninitialized'; 

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

如何:

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

要在两种情况下,正则表达式捕获$ 1,尝试:

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

因为''会捕获'<'和'abc>'之间的'','','<'和'abc>'之间的捕获'/'。

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

唯一不同的是改变 “(/)?”至 ”(/?)”。您已经确定了几个功能解决方案。我认为,这个有你要求的优雅。

我宁愿不使这种分成两个单独的 regexs,一个打开的标签 ,另一个用于关闭标签,因为 然后有需要维持

的 标记列表的两个副本

为什么?将您的标签列表放入一个变量中,并根据您的喜好将该变量插入到尽可能多的正则表达式中。我认为这甚至只有一个正则表达式,因为它更复杂的正则表达式(以及哪个正则表达式并不复杂?)。

要小心尽可能多的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。