在抓取資料時,表格資料會使用製表符號做資料項區隔,方便人眼辨識資訊。
"A B C is Great. D"
利用 “”.split() 可以使用快速以” “做分隔,產生值為 [“A”, “B”, “C”, “is”, “Great.”, “D”]的串列。不過這樣的結果,並不是期望的[“A”, “B”, “C is Great.”, “D”]串列。
因為是製表符產生的空白,所以項目間的空白長度是浮動的,就沒有辦法利用固定長度洗掉。
這裡面有個資料項是敘述類型,中間帶有” “,需要完整呈現,不能把中間的” “被當成split()的依據。這行資料只是一個樣本,每行資料敘述是不是帶有” “,不一定,” “數量多少也不一定。
但仔細觀察,項目與項目中間的空白會有至少兩個,敘述內的空白只會有一個。
說到「至少兩個空白」的規則,可以使用正則表達式,以「” +”」表示。
搭配””.split(),但因為敘述中會有” “,所以要換個分割符,原則上只要不會出現就好,這裡使用「!@#」。
結合兩者,可以得到以下的程式碼
import re
text = "A B C is Great. D"
print(re.sub(" +", "!@#", text).split("!@#"))
# => ['A', 'B', 'C is Great.', 'D']
不過,有時候會產生歪斜的字串,可能會出現以下情況
" A B C is Great. D"
或是自己鐵了心不想使用re,不想多引用一個套件。
上述的字串經過””.split(” “)以雙空白分割後,串列內會有許多””的,這部分不需要,這時候可以使用filter()將其過濾掉。
filter()這個類別可以設定條件去過濾串列,符合條件的會被過濾掉,留下沒有被過濾掉的。我們可以把””濾掉,””相等None,於是可以寫成以下。
text = " A B C is Great. D"
print(text.split(" "))
# => ['', 'A', '', '', ' B', '', 'C is Great.', '', '', '', '', '', '', '', '', '', ' D']
fliter_text = filter(None, text.split(" "))
print(list(fliter_text))
# => ['A', ' B', 'C is Great.', ' D']
雖然項目數目是正確的,但資料項可能會有空白,這是因為單數長度的空白分隔導致,不過也好處理多了。使用””.strip(),可清除頭尾空白。
text = " A B C is Great. D"
fliter_text = filter(None, text.split(" "))
print([row.strip() for row in list(fliter_text)])
# => ['A', 'B', 'C is Great.', 'D']