Фиксированная ширина говорит мне 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'
]
];