使用正则表达式修改$ self中的属性

时间:2015-09-02 10:09:14

标签: regex perl object whitespace moose

我是perl的新手,我在修改$self中保存的属性时遇到了问题。

我有一个名为" devices"在$self内,如果我在perl调试器中打印它,就会打印出来:

DB<22> x $self->{devices}
0  ARRAY(0xa1ec308)
0  "BG-SOKU-SAA01\cM\cJBG-SOKU-TS01 BG-SOKU-DCN01"

现在我想在上面的属性中用逗号替换\cM\cJ和空白。所以我正在写一个正则表达式,就像这样:

my @dM= @{$self->{devices}};
$dM[0]=~ s/\cM\cJ/,/g;
$dM[0]=~ s/ /,/g;

现在当我打印$self->{devices}时,它给了我这个:

DB<22> x $self->{devices}
0  ARRAY(0xa1ec308)
0  'BG-SOKU-SAA01,BG-SOKU-TS01,BG-SOKU-DCN01'

RegEx可以工作但是当我将它传递给其他类并尝试迭代它时,它将逗号分隔的设备名称作为一个单独的值而不是每个设备名称。

我不知道出了什么问题。

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:2)

我认为你的问题是$self -> {devices}实际上是一个单个元素数组 - 包含字符串'BG-SOKU-SAA01,BG-SOKU-TS01,BG-SOKU-DCN01'

暗示你希望这是一个数组 - 这可以通过split

相对容易地实现
@{$self -> {devices}} = map { split /,/ } @{$self -> {devices}} 

鉴于您已经已经首先在分隔符上进行转换 - 您可能也可以这样做。

@{$self -> {devices}} = map { split /(?:\\cM\\cJ|\s+)/ } @{$self -> {devices}}

map是其中一个“黑魔法”perl函数 - 它的作用是列表转换。

  • 我们采用源列表 - 在本例中为@{$self -> {devices}}
  • 遍历它应用代码块。 split /,/ - 这将返回零个或多个元素(我们将每个元素拆分为逗号),这些元素将添加到 new 列表中。
  • 然后我们分配新列表。

这基本上与:

相同
my @new_list;

foreach my $element ( @{$self -> {devices}} ) {
    my @tmp = split /,/, $element;
    push ( @new_list, @tmp ); 
}

$self -> {devices} = \@new_list; 

第二个示例基本相同,但使用split可以采用正则表达式的事实。

使用:(?:\\cM\\cJ|\s+)

因此我们调用:\cM\cJ分隔符 \s+,它是“一个或多个空格”的正则表达式。这就是它处理标签,换行,多个空格等的原因。

注意 - 开始时(?:很重要,因为它表示非捕获组。如果您使用捕获(通常为()),那么它将作为地图操作的一部分被“返回”,因此您最终会得到一个不需要的元素\cM\cJ,因为正则表达式捕获了它。

尝试掌握Data::Dumper

use Data::Dumper;

然后

print Dumper $self;

这有助于您了解对象的内容。