固定宽度表示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'
]
];
来源
2011-12-15 00:08:28
TLP
谢谢!我将`。+`的第一个实例更改为`。+?`,以使模式匹配不成立。这帮助我使用包含“:”字符的值。 – NeonD 2011-12-14 21:44:38