2012-07-15 69 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

相關問題