2013-03-15 77 views
1

我一直在嘗試每種方式,無論我做什麼,都會得到一個空白輸出。這裏是什麼,我有我的文件,我試圖導入和解析一個縮短版:使用RegEx從假標籤之間提取數據(不能使用BeautifulSoup)

<PRESOL> 
<DATE>0310 
<AGENCY>Defense Logistics Agency 
<DESC>*(this is full of HTML tags and the such)* 
<URL>https://www.fbo.gov/spg/DLA/J3/DSCR-BSM/SPE4A713R0575/listing.html 
<SETASIDE>N/A 
</PRESOL> 

我想創建一個表,每個日期列,代理,DESC,URL和SETASIDE,因爲在「PRESOL」標籤之間有100個條目。在每個標籤的數據之後還有返回值,當我將它拉入python時,它會以「\ n」的形式出現。以下是我試過到目前爲止的正則表達式(s是我在閱讀文件,並重新已導入的變量):

testall = re.findall(r'<PRESOL>\n<DATE>(.*?)\n<AGENCY>(.*?)\n<DESC>(.*?)\n<URL>(.*?)\n<SETASIDE>(.*?)\n</PRESOL>', s) 

我想這沒有「\ n」的以及與(+ ?) 代替 (。*?)。

如果您需要更多信息以幫助我,並且非常感謝您的幫助,請告知我們。我的最終遊戲是輕鬆地從ftp://ftp.fbo.gov/FBOFeed20130311(似乎有多種表格類型)導入數據,但我現在專注於PRESOL,只是爲了讓這個概念證明離題。

+0

當我輸出testall它給了我[] – Jared 2013-03-15 02:39:08

+0

這似乎不忍心XML任何關係(這好像是你自己發明的一種標記語言)。你爲什麼把它標記爲XML? – 2013-03-15 09:03:41

+0

我不確定它是否是某種我只是不理解的XML。 – Jared 2013-03-15 14:47:53

回答

1

花了一些時間,並能夠建立一個解析器函數的FBO數據。懷疑你仍然需要它,但也許這會幫助別人。

def fbo_parser(fbo): 
    split_fbo = fbo.split('<PRESOL>') 
    n_ops = len(split_fbo) 
    all_ops_dict = {} 
    for i in range(1, n_ops): 
     strings = fbo.split('<PRESOL>')[i].replace('</PRESOL>', '') 
     strings = strings.split('<') 
     lists = [x.split('>') for x in strings] 
     opp_dict = {} 
     desc_count = 0 
     desc = ['OpDesc', 'URL_Desc', 'EMAIL_Desc'] 
     for ii in lists: 
      if len(ii) == 2: 
       if ii[0] == 'DESC': 
        #TODO: Figure out a better name for the duplicate DESC 
        ii[0] = ii[0] + str(desc_count) 
        desc_count += 1 

       opp_dict[ii[0]] = ''.join([x for x in filter(None, ii[1].split('\\n'))]) 
     all_ops_dict[i] = opp_dict 
    return all_ops_dict 

f = open('FBOFeed19991231', 'rb') 
fbo = str(f.read()) 
fbop = fbo_parser(fbo) 

fbop[68] 
RETURNS:>> 
{'ADDRESS': '[email protected]', 
'AGENCY': 'Department of the Air Force', 
'CLASSCOD': '32', 
'CONTACT': 'Christel Wittmer, Ms., Phone (49) 631 3539 174, Fax (49) 631 3539 158, Email [email protected] - Ursula Nabinger, Ms., Phone (49) 631 3539 178, Fax (49) 631 3539 158, Email [email protected]', 
'DATE': '0720', 
'DESC0': 'WORKBENCH FOR VEHICLE MAINTENANCE,2 METER LONG, TOP IS METAL COVERWERKBANK, 2 METER LANG, SCHICHSTOFF OEL AND FEUCHTIGKEITSBESTAENDIG (22EA/STCK)WORKBENCH FOR VEHICLE MAINTENANCE, 2 METER LONG TOP CONSISTS 40 MM TICK WOODWERKBANK, 2 METER LANG ARBEITSPLATTE HOLZ MEHRSCHICHTVERLEIMTESBUECHENHOLZ (22EA/STCK)FOR MORE INFO CALL MRS WITTMER 0631-3539-174!', 
'DESC1': 'Link to FedBizOpps document.', 
'DESC2': 'Christel Wittmer', 
'EMAIL': '', 
'LINK': '', 
'LOCATION': '700 CONS', 
'OFFADD': 'United States Air Force, United States Air Force Europe, Rhine Ordnance Barracks, USAFE CONS, UNIT 3115, Germany, . 09094-3115', 
'OFFICE': 'United States Air Force Europe', 
'RESPDATE': '073099', 
'SOLNBR': 'F61521-99T0607', 
'SUBJECT': 'WORKBENCH FOR VEHICLE MAINTENANCE', 
'URL': 'http://www.fbo.gov/spg/USAF/USAFE/ROB/F61521-99T0607/listing.html', 
'YEAR': '99', 
'ZIP': '09021'} 
+0

我不再需要這個,但前同事可能會這麼做,所以謝謝你與社區分享! – Jared 2017-05-22 15:25:07

+0

就像給你,你的同事或任何其他需要這個的人一樣......我從那以後玩了更多,並且已經意識到這仍然不是一個完美的解決方案。我正在積極處理這些數據,並會在我去的時候嘗試更新這篇文章,或者至少推送到我的github @ https://github.com/usmcamp0811/FBO_Parser – 2017-05-23 13:39:59

0

我看到在FTP下面的例子(我切出第一場專注於popaddress):

In [7]: data = """<PRESOL> 
    ...: <DESC>Link To Document 
    ...: <SETASIDE>N/A 
    ...: <POPCOUNTRY>US 
    ...: <POPADDRESS>Moody AFB, GA 
    ...: Avon Park, FL 
    ...: </PRESOL>""" 

In [11]: re.findall(r'<PRESOL>\n<DESC>(.*?)\n<SETASIDE>(.*?)\n<POPCOUNTRY>(.*?)\n<POPADDRESS>(.*?)\n</PRESOL>', data) 
Out[11]: [] 

至於最後一個字段具有\ n後面沒有標籤,它不匹配這就是問題所在。

觀察FTP中的數據我發現還有其他多行字段,如DESC,CONTACT,在某些情況下很大並且被H TML標籤。也許你最好使用更多算法的方法,而不是試圖用一個正則表達式來解析整個「行」數據。我認爲可能會有足夠的角落案例考慮在這一行一行。

祝你好運!

+0

我認爲在將它應用於ftp鏈接上的數據時它並不起作用 – 2013-03-15 01:37:59

+0

我用正則表達式想到了,您可以說「給我所有文本在之間」,正如我以前在過去,但由於某種原因,這給我很多問題。 – Jared 2013-03-15 02:37:59

+0

您可以使用re.M標誌指定多行匹配。儘管如此,我認爲這個問題不適合正則表達式(儘管也許你有興趣使用/練習它們,在這種情況下它就好)。祝你好運 – Mariano 2013-03-17 23:35:19

0

下面是創建一個可以打開變成一個表的數據結構的一個想法:

presol = [] 
split = re.split('<\/PRESOL>', file_data) 

for s in split: 
    d = {} 
    for k,v in re.findall('<([^>]+)>(.[^<]+)\n', s, re.M|re.S): 
     d[k]=v 
     presol.append(d) 

print("DATE\tAGENCY\tDESC\tURL\tSETASIDE\n") 
for p in presol: 
    print("%s\t%s\t%s\t%s\t%s\n"%(p["DATE"], p["AGENCY"], p["DESC"], p["URL"], p["SETASIDE"])) 
相關問題