Perl 用逗号分割函数
Posted
技术标签:
【中文标题】Perl 用逗号分割函数【英文标题】:Perl Split function with comma 【发布时间】:2013-04-16 04:06:50 【问题描述】:我有一个文件,其中包含以下行,
<tag host="xyz|abc" some info />
<tag host="ijk,cdf" some info />
我正在使用模式匹配获取主机的信息,我想拆分主机的值。出于某种原因,即使看起来正确,以下代码似乎也不适用于逗号。
if($line =~ m/(\s\S)*host=\"(\S+)\"(\s\S)*/)
($val) = ($2);
$val=~tr/!$()//ds;
my @values;
if($val =~ m/((\S+)\|(\S+))*/ )
@values=split('\|',$val);
else
@values=split(',',$val);
#Perform some action on Values.
谁能帮我解决这个问题?提前致谢。
【问题讨论】:
你的输入是什么样的? 为什么要把它分解成if-else
?为什么不直接用逗号或竖线分割(例如split /[,\|]/,$val;
)?
【参考方案1】:
一些想法:
use strict
, use warnings
和一些缩进会很好:)
你在哪里写了(\s\S)
我想你熟悉 javascript 并且指的是 字符类 [\s\S]
?您感兴趣的部分前后的文字无需匹配
tr///
上的 /s
修饰符与 /d
一起使用是多余的
只收集既不是竖线也不是逗号的字符的所有子字符串要容易得多
这就是我的写法
use strict;
use warnings;
while (my $line = <DATA>)
if ($line =~ m/host="(\S+)"/)
(my $href = $1) =~ tr/!$()//d;
my @values = $href =~ /[^,|]+/g;
print "@values\n";
__DATA__
<tag host="xyz|abc" some info />
<tag host="ijk,cdf" some info />
输出
xyz abc
ijk cdf
【讨论】:
【参考方案2】:您的代码中不需要if-else
。您可以将条件组合成一行代码。
像这样更改您的代码:
use strict;
use warnings;
if($line =~ m/(\s\S)*host=\"(\S+)\"(\s\S)*/)
($val) = ($2);
$val=~tr/!$()//ds;
my @values;
@values = split (/[,|]/,$val);
#Perform some action on Values.
【讨论】:
当然,该代码不会在strict
下编译。并且捕获 $1
和 $3
看起来是不必要的 → /host="([^"]+)"/
将是一个更好的正则表达式。 split
正则表达式将对host="xyz|abc,def"
等输入产生有趣的影响。使用split
的第三个参数将生成的片段限制为两个可能是个好主意。
无需在字符类中转义管道
我对相同的代码还有一个问题。我正在检查每个值是否存在于数组列表中,如果没有,我将基于此采取行动。 if(!grep($_,@hosts_ignore_list) #Perform an Operation 这似乎也不起作用。@hosts_ignore_list 包含一个名为 dummy 的元素。但条件总是评估为 false,因为 grep 函数返回整个数组以防万一它没有找到特定的字符串。以上是关于Perl 用逗号分割函数的主要内容,如果未能解决你的问题,请参考以下文章