最近在處理一份數據,初一看,這是xml格式,果斷百度如何用Python解析xml,感覺甚是高大上。但是,細節決定成敗啊,通過解析時遇到的bug發現,這數據竟不是標準的xml,原因有二:
1.tag的屬性值應該用雙引號引上,但是這份數據沒有。舉個栗子:
正確:<seg id="123">
錯誤:<seg id=123>
這樣在用xml.etree.ElementTree解析的時候是會報錯的,會指出是‘’不好的格式‘’。
2.tag不封閉,舉例就是隻有<seg>
而沒有</seg>
。
起初發現問題1的時候,我還天真的要修正這份數據,把tag的屬性值的雙引號補上,於是有了下面這段代碼(順便學了一點re)
'''這是部分重點代碼,不完整'''
import re
pattern1 = re.compile(r'<TEXT ID=(.+)>') #定義一個匹配模式
with open(source_path,'r',encoding='utf-8') as old_file:
with open(goal_path,'w',encoding='utf-8') as new_file:
for line in old_file.readlines():
if pattern1.findall(line):
res = pattern1.findall(line) #這裏res就是沒有引號的屬性值
line = '<TEXT ID=\"'+ res[0] + '\">\n'
new_file.write(line)
本以爲到此雙引號已經補上,就可以用xml.etree.ElementTree解析數據了,把標籤中的數據提取出來,如此便大功告成。於是開心的寫了下面的代碼:
'''提取中TEXT標籤之間的數據,刪除數據之間的空白符和換行符,連成一句話,然後返回'''
import xml.etree.ElementTree as ET
import re
tree = ET.parse(data_path)
root = tree.getroot()
del_space = re.compile('[ \t\n]*')
sentences = []
if root.iter('TEXT'): #找到TEXT標籤,返回迭代器
for elem in root.iter('TEXT'):
sent = del_space.sub('',elem.text) #作用是刪除一段內容的空白符和換行符
sentences.append(sent)
return sentences
對於格式良好的xml,上面的代碼OK,但是如果tag不封閉,etree會報錯。
至此,我決定放棄用解析xml的方法提取數據。那怎麼辦,返璞歸真,直接上re,找規律,用re匹配。好吧,這也算是一個經驗吧,高級的工具處理高級的問題,如果要解決的問題比較“粗糙”,那就用比較“魯棒”的方法來解決。