使用正则表达式修改 $self 中的属性
modifying attribute in $self using regex
我是 perl 的新手,我在修改 $self
中保存的属性时遇到问题。
我在 $self
中有一个名为 "devices" 的属性,如果我在 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 可以工作,但是当我将它传递给其他 class 并尝试对其进行迭代时,它会将逗号分隔的设备名称作为一个单一值,而不是每个设备名称都采用 1 个。
我不知道出了什么问题。
请帮我解决这个问题。
我认为您的问题是 $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
是那些 "dark magic" perl 函数之一 - 它所做的是列表转换。
- 我们采用源列表 - 在本例中
@{$self -> {devices}}
- 应用代码块遍历它。
split /,/
- 这个 returns 零个或多个元素(我们用逗号分隔每个元素),它被添加到 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+
是 "one or more whitespace" 的正则表达式。这就是它处理制表符、换行符、多个空格等的原因。
注意 - 开头的 (?:
很重要,因为它表示一个非捕获组。如果您使用捕获(()
通常)那么这将是 'returned' 作为映射操作的一部分,因此您最终会得到一个不需要的元素 \cM\cJ
因为正则表达式捕获了它.
尝试掌握 Data::Dumper
。
use Data::Dumper;
然后
print Dumper $self;
这将帮助您了解对象的内容。
我是 perl 的新手,我在修改 $self
中保存的属性时遇到问题。
我在 $self
中有一个名为 "devices" 的属性,如果我在 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 可以工作,但是当我将它传递给其他 class 并尝试对其进行迭代时,它会将逗号分隔的设备名称作为一个单一值,而不是每个设备名称都采用 1 个。
我不知道出了什么问题。
请帮我解决这个问题。
我认为您的问题是 $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
是那些 "dark magic" perl 函数之一 - 它所做的是列表转换。
- 我们采用源列表 - 在本例中
@{$self -> {devices}}
- 应用代码块遍历它。
split /,/
- 这个 returns 零个或多个元素(我们用逗号分隔每个元素),它被添加到 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+
是 "one or more whitespace" 的正则表达式。这就是它处理制表符、换行符、多个空格等的原因。
注意 - 开头的 (?:
很重要,因为它表示一个非捕获组。如果您使用捕获(()
通常)那么这将是 'returned' 作为映射操作的一部分,因此您最终会得到一个不需要的元素 \cM\cJ
因为正则表达式捕获了它.
尝试掌握 Data::Dumper
。
use Data::Dumper;
然后
print Dumper $self;
这将帮助您了解对象的内容。