Разбор абзаца с помощью 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

Док:

Чтобы понять ссылки, я рекомендую вам несколько указателей:

Другие вопросы по тегам