2012-07-15 144 views
-2

我有以下输入。我想解析它为CSV分隔字符串。我可以通过正则表达式模式获得SKU,但由于我对正则表达式解析不熟悉,因此我不了解复杂模式。如果有人能帮助我,这将是很好的。如何使用Python中的正则表达式从文本中提取信息?

谢谢!

charset="iso-8859-1" 


BODY { 


} 



TD { 



} 



TH { 


} 



H1 { 


} 

TABLE,IMG,A { 


} 

**PO Number:** 35102 


**Ship To:** 


Georgie Clements 



6902 Stonegate Drive 

Odessa, TX 79765 



432-363-8459 


SKU 



Product 



Qty 


JJ-Rug-Zebra-PK 



Zebra Pink Rug 



1 

JJ-Zebra-PK-Twin-4 



Zebra Pink 4 Piece Twin Comforter Set 



1 



JJ-TwinSheets-Zebra-PK 



Zebra Pink 3 Piece Twin Sheet Set 



1 




JJ-Memo-Zebra-PK 



Zebra Pink Memory Board 



1 

我希望它这样的格式:

PONumber, Shipping info, SKU, Product, Qty 
'35102', '[ShipToAddress]', 'JJ-Rug-Zebra-PK', 'Zebra Pink Rug', '1' 
'35102', '[ShipToAddress]', 'JJ-Zebra-PK-Twin-4', 'Zebra Pink 4 Piece Twin Comforter Set', '1' 
'35102', '[ShipToAddress]', 'JJ-TwinSheets-Zebra-PK', 'Zebra Pink 3 Piece Twin Sheet Set', '1' 
'35102', '[ShipToAddress]', 'JJ-Memo-Zebra-PK', 'Zebra Pink Memory Board', '1' 

当前的代码如下:

pattern = re.compile(r'(\b\w*JJ-\S*)') 

pos = 0 
    while True: 
     match = pattern.search(msgStr, pos) 
     if not match: 
      break 
     a = match.start() 
     e = match.end() 
     print ' %2d : %2d = %s' % (a, e-1, msgStr[a:e]) 
     pos = e 
+0

您的正则表达式到目前为止看起来如何? – jdi 2012-07-15 14:54:38

+5

另外,一个正则表达式不适合这个问题。它需要具有状态的解析方法。每行都必须进行评估,以确定您是否正在捕获不同的数据集。 – jdi 2012-07-15 14:57:04

+0

图案= re.compile(R '(\ B \ W * JJ- \ S *)') POS = 0 而真: 匹配= pattern.search(msgStr,POS) 如果不匹配: 破 一个= match.start() E = match.end() 打印 '%2d中:%2d中=%s' 的%\ (A,E-1,msgStr [A:E]) POS = E – 2012-07-15 15:01:24

回答

1

这里的另一种解决方案,不使用正则表达式:

s = "(your data as a single multiline string)" 

datalines = lambda s: [ln for ln in (line.strip() for line in s.splitlines()) if ln] 

_, _, po_number, _, rem = s.split('**') 
shipto, data = rem.split('SKU', 1) 

po_number = datalines(po_number)[0] 
shipto = '\n'.join(datalines(shipto)) 
data  = datalines(data)[2:] 

res = [[po_number, shipto, sku, prod, qty] for sku,prod,qty in zip(*([iter(data)]*3))] 

这给最终的结果

[ 
    ['35102', 'Georgie Clements\n6902 Stonegate Drive\nOdessa, TX 79765\n432-363-8459', 'JJ-Rug-Zebra-PK', 'Zebra Pink Rug', '1'], 
    ['35102', 'Georgie Clements\n6902 Stonegate Drive\nOdessa, TX 79765\n432-363-8459', 'JJ-Zebra-PK-Twin-4', 'Zebra Pink 4 Piece Twin Comforter Set', '1'], 
    ['35102', 'Georgie Clements\n6902 Stonegate Drive\nOdessa, TX 79765\n432-363-8459', 'JJ-TwinSheets-Zebra-PK', 'Zebra Pink 3 Piece Twin Sheet Set', '1'], 
    ['35102', 'Georgie Clements\n6902 Stonegate Drive\nOdessa, TX 79765\n432-363-8459', 'JJ-Memo-Zebra-PK', 'Zebra Pink Memory Board', '1'] 

编辑:秒数据文件返回

[ 
    ['35104', 'Angelica Alvarado\n669 66th St.\nSpringfield, OR 97478\n5412322525', 'JJ-CribSheet-Cheetah-PK-PRT', 'Cheetah Pink Print Microsuede Crib Sheet', '1'] 
] 

其上检查似乎是正确的?


最后的总结:我发现,他用html2text到HTML电子邮件到文本的转换,那么试图解析它。解决方案是直接使用BeautifulSoup解析html,利用页面结构来识别他想要的字段。

+0

谢谢我会给它一个去 – 2012-07-15 21:36:53

+0

其给我错误这里的转储出错了! <类型 'exceptions.ValueError'> 回溯(最近最后调用): 文件 “processUploads.py”,第39行,在 _,_,PO_NUMBER,_,REM = s.split( '**') ValueError异常:需要比1点的值更解压 – 2012-07-15 21:49:37

+0

@AMalik:它看起来像你的数据字符串中不包含任何'**的? – 2012-07-15 22:25:59

1

按照该意见,这种输入数据的更适合一种有状态的解析方法,而不是正则表达式解决方案。有些行表示解析状态应该改变以捕获一组新的数据。

理想情况下,首先你会看到这个数据源是否可用JSON而不是我认为是HTML的webscraping。拥有JSON源将使这个过程变得微不足道,因为数据已经是对象格式。

如果您唯一的选择是使用这个逐行的源代码,那么您最好使用类似pyparsing的东西,或者如果这被认为是针对您的需求的矫枉过正,您可以循环遍历并检查每一行一个看你是否应该开始或停止收集一种类型的数据,直到下一个令牌。

作为最后的手段,您可以在整个输入中运行多个正则表达式模式。您必须在整个输入上运行它的原因是因为您的数据跨越了行。为捕捉SKU /产品的一个基本的正则表达式/数量可能是:

re.findall(r'(JJ-[\w-]+)\n+(.*?)\n+(\d+)\n', dataStr) 
#[('JJ-Rug-Zebra-PK', 'Zebra Pink Rug', '1'), 
# ('JJ-Zebra-PK-Twin-4', 'Zebra Pink 4 Piece Twin Comforter Set', '1'), 
# ('JJ-TwinSheets-Zebra-PK', 'Zebra Pink 3 Piece Twin Sheet Set', '1'), 
# ('JJ-Memo-Zebra-PK', 'Zebra Pink Memory Board', '1')] 

这将找到包含这些模式的每一个3线,并返回一个元组列表。我真的不推荐正则表达式的方法,但它是一个选项。

其他的正则表达式:

re.search(r'\*{2}PO Number:\*{2}\s(\d+)\n', dataStr) 
#('35102',) 

re.search(r'\*{2}Ship To:\*{2}\s+(.*?)\s+SKU', dataStr, re.DOTALL) 
#('John Doe\n6902 Stonegate Drive\nOdessa, TX 79\n000-000-0000',) 

你可以看你怎么会只需要建立单独的正则表达式为每个数据位。

+0

我想,你正在寻找的SKU与-PK结束只,但如果你看到的数据在那里你的正则表达式不起作用在我提供的源代码中,情况并非如此,并且模式失败。 – 2012-07-15 15:38:42

+0

只需删除'-PK'。你可以看到这是如何变成“精确模式” VS的解析方法的游戏“此行表示,我们现在采取的产品数据,所以要在未来3行作为产品” – jdi 2012-07-15 15:42:36

+0

我会改变源,因为它是和希望你运行你的模式,你会发现自己所指的 – 2012-07-15 15:55:16

相关问题