我公司有一个客户跟踪不同地点不同公司的产品价格.此信息将进入数据库.
这些公司每天通过电子邮件将价格发送给我们的客户,当然电子邮件的格式也不同.任何公司都不可能改变他们的格式 - 他们不会这样做.
有些看起来像这样:
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
其他人看起来像这样:
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
目前,我们为每个公司的电子邮件格式编写了单独的解析器.但这些格式经常变化不大.我们不能指望每次都在同一行或列上的价格.
我们查看电子邮件并确定哪个价格与哪个产品位于哪个位置是微不足道的.但对我们的代码而言并非如此.因此,我正在尝试寻找更灵活的解决方案,并希望您就采取何种方法提出建议.我对从正则表达式到神经网络的任何事情持开放态度 - 我将学习如何使这项工作成功,我只是不知道我需要学习什么.这是一个lex/parsing问题吗?更类似于OCR?
代码不必单独找出所有格式.电子邮件分为几个主要的'样式',如上所述.我们确实需要代码足够灵活,以至于新产品系列或空格或某些内容不会使文件无法解析.
感谢您提供有关从哪里开始的任何建议.
我认为这个问题适合于正确的解析器生成器.正则表达式如果出错就太难以测试和调试.但是,我会选择一个易于使用的解析器生成器,就像它是语言的一部分一样.
对于这些类型的任务,我会选择pyparsing,因为它具有完整的lr解析器的功能,但没有难以定义的语法和非常好的辅助函数.代码也很容易阅读.
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
这将返回列表列表.
['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']
您可以根据需要对事物进行分组,但为了简单起见,我刚刚返回了列表.默认情况下会忽略空格,这会使事情变得简单得多.
我不知道是否有其他语言的等价物.