固定宽度unpack
对我说。可以使用正则表达式进行解析和拆分,但unpack
应该是更安全的选择,因为它是固定宽度数据的正确工具。
我将第一个字段的宽度设置为 12,将中间的空白空间设置为 13,这适用于该数据。你可能需要改变它。该模板的"A12A13A*"
意思是“找到 12 个然后是 13 个 ascii 字符,然后是任意长度的 ascii 字符”。unpack
将返回这些匹配项的列表。此外,如果未提供字符串,unpack
将使用,这就是我们在这里所做的。$_
请注意,如果第一个字段直到冒号的宽度不是固定的,因为它似乎在您的示例数据中,您需要合并模板中的字段,例如“A25A*”,然后去掉冒号。
我选择数组作为存储设备,因为我不知道您的字段名称是否唯一。哈希将覆盖具有相同名称的字段。数组的另一个好处是它保留了数据在文件中出现的顺序。如果这些事情无关紧要并且快速查找更重要,请改用哈希。
代码:
use strict;
use warnings;
use Data::Dumper;
my $last_text;
my @array;
while (<DATA>) {
# unpack the fields and strip spaces
my ($field, undef, $text) = unpack "A12A13A*";
if ($field) { # If $field is empty, that means we have a multi-line value
$field =~ s/:$//; # strip the colon
$last_text = [ $field, $text ]; # store data in anonymous array
push @array, $last_text; # and store that array in @array
} else { # multi-line values get added to the previous lines data
$last_text->[1] .= " $text";
}
}
print Dumper \@array;
__DATA__
field name 1: Multiple word value.
field name 2: Multiple word value along
with multiple lines.
field name 3: Another multiple word
and multiple line value
with a third line
输出:
$VAR1 = [
[
'field name 1:',
'Multiple word value.'
],
[
'field name 2:',
'Multiple word value along with multiple lines.'
],
[
'field name 3:',
'Another multiple word and multiple line value with a third line'
]
];