【问题标题】:Perl Split function with commaPerl 用逗号分割函数
【发布时间】: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;)?

标签: perl split comma


【解决方案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 函数返回整个数组以防万一它没有找到特定的字符串。
    猜你喜欢
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 2022-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多