Разбор абзаца с помощью perl
У меня есть большое количество PDF-файлов. Это ежемесячные публикации, и я хотел бы автоматизировать копирование и анализ этих документов, чтобы получить контактную информацию для импорта в БД.
Скажем, есть теги START и END для каждого блока текста. Мне нужно взять "Comapny" после начального тега, пропустить "(Parantheses)" и PARAgraph между ними, затем очистить PARTNER_COMPANY, "Title" и различные формы контактной информации до END TAG, а затем на следующем. Строки контактной информации могут отличаться. У некоторых может быть дополнительная информация, чем у других, но мне все равно она нужна в едином формате, который следует за конкретным заголовком. Для вариантов, штат, страна и почтовый индекс могут находиться на одной строке, разделенной символом,. Другие варианты этого могут быть разделены \n. Когда программа достигает раздела "Дата" файлов, даты должны быть проанализированы в определенном формате (см. Ниже). Некоторые блоки текста предоставят всю эту контактную информацию, другие - нет. Я хочу разобрать до конца тега.
ПРИМЕР ДАННЫХ
START
Company_1_ANY type of character
(Parantheses)
PARAgraph
DATE: Dated this 5 day of NOvermber 2014 - parse date to yyyy-mm-dd format(2014-11-05)
PARTNER_COMPANY_1
Title - title_1
Contact for enquiries: - CONTACT PERSON
HOMER Simpson
Telephone: (123) 123-1234
FAX: (111) 346-0000
Address:
P.O. Box 123454, ANYTown, 12345-1234
STATE, USA
END
START
COMPANY_2_ANY type of character
(Parantheses)
PARAGRAPH of random text
Dated this 5 day of November 2014 - 2014-11-05
PARTNER_COMPANY_2
Title - Title_2
address:
190 RAndom Avenue, Any town
STATE_2 12345-0987
Country - USA
Contact:
JOsh E
Telephone: (234) 111-1111
END
КОД
my @name;
while (<>) {
if (/START/gism) {
while (<>) {
last if /END/;
chomp;
push @name, $_;
}
print "\t@name\n";
@name = ()
}
else {
print '';
}
}
МОИ РЕЗУЛЬТАТЫ
Company_1_ANY type of character (Parantheses) PARAgraph DATE: Dated this 5 day of NOvermber 2014 - parse date to yyyy-mm-dd format(2014-11-05) PARTNER_COMPANY_1 Title - title_1 Contact for enquiries: - CONTACT PERSON HOMER Simpson Telephone: (123) 123-1234 FAX: (111) 346-0000 Address: P.O. Box 123454, ANYTown, 12345-1234 STATE, USA
COMPANY_2_ANY type of character (Parantheses) PARAGRAPH of random text Dated this 5 day of November 2014 - 2014-11-05 PARTNER_COMPANY_2 Title - Title_2 address: 190 RAndom Avenue, Any town STATE_2 12345-0987 Country - USA Contact: JOsh E Telephone: (234) 111-1111
ЖЕЛАЕМЫЙ ВЫХОД
Company,DATE,PARTNER_COMPANY,Title,CONTACT PERSON,Telephone,FAX,Address,City,STATE,ZIP,Country
Company_1,2014-11-05,PARTNER_COMPANY_1,title_1,HOMER Simpson,(123) 123-1234,(111) 346-0000,P.O. Box 123454,ANYTown,12345-1234,USA
COMPANY_2,2014-11-05,PARTNER_COMPANY_2,Title_2,JOsh E,(234) 111-1111,,190 RAndom Avenue,Any town,STATE_2,12345-0987,USA
Я получаю то, что хочу между START и END, но я не уверен, как разграничить элементы в моем массиве. Кроме того, я не могу понять, как отфильтровать нежелательные, то есть ПАРАГРАФ. Я также хотел бы урезать то, что находится между разделителями. Я знаю, что модуль может быть полезен в этом, но для меня, чтобы лучше понять, как создать хэш и / или ключи, есть ли лучший способ?
Кроме того, в строках DESIRED OUTPUT игнорируйте приведенный разрыв строки. Строка должна продолжаться через запятую. Этот поток будет позволять тексту только определенной длины, пока строка не обрывается.
1 ответ
Рассматривайте этот сценарий как основу, он требует больше работы, чтобы полностью соответствовать вашим потребностям. Он хранит информацию в структуре данных Perl (DS): HASH. Обработка завершена, вам просто нужно перебрать DS для получения желаемого результата:
#!/usr/bin/env perl
use strict; use warnings; # always put this in your scripts
use Data::Dumper; # to print the data structure (DS) like in my OUTPUT section
my $h = []; # $h is a reference to a void ARRAY
my $witness1 = my $witness2 = 0; # setting the 2 variables with '0'
my $key = -1;
# using the magic 'diamond operator <>' to loop through the input file
while (<DATA>) {
next if /^$/; # skip this line if it's a blank line
$key++ if /^START/; # iterating $key if the current line begins with 'START'
# setting HASH values, $& is the matching part
$h->[$key]->{Company} = $& if /^Company_.*/i;
$h->[$key]->{Partner_Company} = $& if /^PARTNER_COMPANY.*/i;
$h->[$key]->{Title} = $& if /^TITLE\s+-\s+\K.*/i;
# if there's 'CONTACT PERSON' string in the current line
if (/CONTACT\s+PERSON/) {
$witness1 = 1;
next;
}
# witness1 tell us that we still are in the 'CONTACT PERSON' part
if ($witness1) {
$h->[$key]->{Name} = chomp($_);
$witness1 = 0;
}
$h->[$key]->{Tel} = $& if /^Telephone: \K.*/i;
$h->[$key]->{Fax} = $& if /^FAX: \K.*/i;
if (/^Address:/i) {
$witness2 = 1;
next;
}
# witness2 tell us that we still are in the 'ADDRESS' part
if ($witness2 and !/^END/) {
$h->[$key]->{Address} .= $_;
}
if (/^END/) {
$witness2 = 0;
}
}
print Dumper $h;
__DATA__
START
Company_1_ANY type of character
(Parantheses)
PARAgraph
DATE: Dated this 5 day of NOvermber 2014 - parse date to yyyy-mm-dd format(2014-11-05)
PARTNER_COMPANY_1
Title - title_1
Contact for enquiries: - CONTACT PERSON
HOMER Simpson
Telephone: (123) 123-1234
FAX: (111) 346-0000
Address:
P.O. Box 123454, ANYTown, 12345-1234
STATE, USA
END
START
COMPANY_2_ANY type of character
(Parantheses)
PARAGRAPH of random text
Dated this 5 day of November 2014 - 2014-11-05
PARTNER_COMPANY_2
Title - Title_2
address:
190 RAndom Avenue, Any town
STATE_2 12345-0987
Country - USA
Contact:
JOsh E
Telephone: (234) 111-1111
END
Док:
Чтобы понять ссылки, я рекомендую вам несколько указателей: