2009-08-07 14 views
5

Moja firma ma klienta, który śledzi ceny produktów różnych firm w różnych lokalizacjach. Informacje te trafiają do bazy danych.Algorytmy lub wzorce do czytania tekstu

Firmy te wysyłają e-mailem ceny do naszego klienta każdego dnia i oczywiście wszystkie e-maile są sformatowane inaczej. Niemożliwe jest, aby jakakolwiek firma zmieniła swój format - nie zrobią tego.

Niektóre wyglądają jakby tak:

 
    This is example text that could be many lines long... 

    Location 1 
    Product 1  Product 2  Product 3 
    $20.99  $21.99  $33.79 

    Location 2 
    Product 1  Product 2  Product 3 
    $24.99  $22.88  $35.59 

Inne wyglądają trochę jak ten:

 
    PRODUCT       PRICE   +/- 
    ------------  -------- ------- 
    Location 1 
    1             2007.30 +048.20 
    2             2022.50 +048.20 

    Maybe some multiline text here about a holiday or something... 

    Location 2 
    1             2017.30 +048.20 
    2             2032.50 +048.20 

Obecnie mamy indywidualne parser napisane dla każdego formatu e-mail firmy. Ale te formaty dość często się zmieniają. Nie możemy liczyć na to, że ceny są za każdym razem w tym samym wierszu lub kolumnie.

To jest trywialne dla nas, aby spojrzeć na e-maile i ustalić, która cena idzie z jakim produktem, w którym miejscu. Ale nie tak bardzo dla naszego kodu. Dlatego staram się znaleźć bardziej elastyczne rozwiązanie i chciałbym poznać twoje sugestie na temat tego, jakie podejścia podjąć. Jestem otwarty na wszystko, od regexu do sieci neuronowych - nauczę się, co muszę zrobić, aby to działało, po prostu nie wiem, czego potrzebuję się uczyć. Czy to jest problem lex/parsing? Bardziej podobny do OCR?

Kod nie musi samodzielnie formułować formatów. E-maile należą do kilku głównych "stylów", takich jak te powyżej. Naprawdę potrzebujemy, aby kod był wystarczająco elastyczny, aby nowa linia produktów lub biała spacja nie powodowały, że plik był nieopisywalny.

Dzięki za wszelkie sugestie dotyczące tego, od czego zacząć.

+1

Byłoby pomocne, aby zobaczyć, jak analizować jeden z tych formatów już teraz. Ktoś może być w stanie wziąć twój istniejący kod i wskazać, gdzie można go uelastycznić. –

+0

Obecny kod to w zasadzie: jeśli firma jest firmą1, przejdź do trzeciej linii, przeczytaj pierwsze 12 znaków jako produkt, a następnie odczytaj znaki 45-50 jako cenę. Następnie przejdź do czwartej linii ... To bardzo, bardzo trudne kodowanie. –

+0

@Scott, Ok, jeśli białe spacje rozdzielają dane na kolumny tak, jak opisuję w mojej odpowiedzi, możesz wygodnie używać skryptów. – nik

Odpowiedz

7

Myślę, że ten problem byłby odpowiedni dla właściwego generatora analizatora składni. Wyrażenia regularne są zbyt trudne do przetestowania i debugowania, jeśli pójdą źle. Jednak wybrałbym generator parsera, który jest prosty w użyciu tak, jakby był częścią języka.

Do tego typu zadań chodziłem z pyparstwem, ponieważ ma on moc pełnego parseru lr, ale bez trudnego do zdefiniowania gramatyki i bardzo dobrych funkcji pomocniczych. Kod jest również łatwy do odczytania.

from pyparsing import * 

aaa =""" This is example text that could be many lines long... 
      another line 

    Location 1 
    Product 1  Product 2  Product 3 
    $20.99  $21.99  $33.79 

    stuff in here you want to ignore 

    Location 2 
    Product 1  Product 2  Product 3 
    $24.99  $22.88  $35.59 """ 

result = SkipTo("Location").suppress() \ 
# in place of "location" could be any type of match like a re. 
     + OneOrMore(Word(alphas) + Word(nums)) \ 
     + OneOrMore(Word(nums+"$.")) \ 

all_results = OneOrMore(Group(result)) 

parsed = all_results.parseString(aaa) 

for block in parsed: 
    print block 

Powoduje wyświetlenie listy list.

['Location', '1', 'Product', '1', 'Product', '2', 'Product', '3', '$20.99', '$21.99', '$33.79'] 
['Location', '2', 'Product', '1', 'Product', '2', 'Product', '3', '$24.99', '$22.88', '$35.59'] 

Możesz grupować rzeczy tak, jak chcesz, ale dla uproszczenia właśnie zwróciłem listy. Biała spacja jest domyślnie ignorowana, co znacznie upraszcza sprawę.

Nie wiem, czy istnieją odpowiedniki w innych językach.

0

Podałeś dwie próbki wzorów dla plików tekstowych.
Myślę, że można je obsługiwać za pomocą skryptów.
Coś jak: AWK, sed, grep with bash scripting.


Jeden wzór w pierwszej próbce,

  1. Sekcja rozpoczyna się od słowa kluczowego Location [liczba]
    • druga linia sekcja ma kolumny opisujące nazwy produktów
    • trzecia linia sekcja ma kolumny z cenami produktów

W każdej sekcji może znajdować się zmienna liczba produktów.
Może istnieć zmienna liczba sekcji na plik.
Produkty i ceny znajdują się zawsze w wyznaczonych wierszach sekcji.
Separacja białych znaków określa powiązanie kolumn z (product,price).
Liczba produktów w sekcji odpowiada liczbie cen w tej sekcji.


Zgromadzone dane prawdopodobnie być przyswojone w bazie danych.

0

Jedną z rzeczy, których używam, to wyrażenia regularne. Trzy lub cztery wyrażenia mogą sterować logiką parse dla każdego formatu e-mail.

Próbuję napisać silnik analizowania bardziej ogólnie niż to, jak sądzę, omija krawędź overprogramming to.

+0

Dzięki. Właśnie teraz badamy, ponieważ może być tak, że bardziej ogólna metoda może potroić dochody, co zmienia naszą zwykłą definicję "nadmiernego programowania". :) Jeśli masz pomysły na bardziej ogólne metody, nawet jeśli wydają się być przesadą, dodaj je. –