Python複雜場景下字串處理相關問題與解決技巧
阿新 • • 發佈:2018-12-14
1.如何拆分含有多種分隔符的字串¶
''' 實際案例: 我們要把某個字串依據分隔符號拆分不同的欄位,該字串包含多種不同的分隔符,例如: s=’ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz’,其中<,>, <;>, <|>, <\t>都是分隔符號,如何處理? 解決方案: 1.連續使用str.split(),每一次處理一種分隔符號; 2.使用正則表示式的re.split(),一次性拆分字串。 ''' In [1]:#解決方案1.連續使用str.split(),每一次處理一種分隔符號;In [2]:def mySplit(s,ds): res = [s] for i in ds: t = [] # 普通方法 #for x in res: # t.extend(x.split(i)) # 列表解析 #[t.extend(y.split(i)) for y in res if y] # map高階函式,map生成可迭代物件 for z in map(lambda x: x.split(i), res): t.extend(z) # 以上三個方法都可以解決問題 res = t # 去除空字串 return [x for x in res if x]
s="ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz" print(mySplit(s,",;|\t"))
['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
#解決方案2.使用正則表示式的re.split(),一次性拆分字串。 import re s="ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz" re.split(r'[,;|\t]+',s)Out[3]:
['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']
2.如何判斷字串a是否以字串b開頭或結尾¶
''' 實際案例:某檔案系統中目錄下有一系列檔案,a.c,b.sh,d.py,e.java... 編寫程式給其中所以的.sh檔案和.py檔案加上使用者可執行許可權 解決方案:使用字串的str.startwith()和str.endswith()方法, 注意:多個匹配時引數使用元組 ''' In [4]:import os,statIn [5]:
os.listdir('.')Out[5]:
['.ipynb_checkpoints', 'graph.py', 'stack.cpp', 'heap.java', 'install.sh', 'quicksort.c', '複雜場景下字串處理相關問題與解決技巧.ipynb']In [6]:
s = 'heap.java'In [7]:
s.endswith('.java')Out[7]:
TrueIn [8]:
#endswith可以接受一個元組(不能使列表)為引數,滿足其中之一,就會返回True [name for name in os.listdir('.') if name.endswith(('.sh','.py'))]Out[8]:
['graph.py', 'install.sh']In [9]:
#st_mode是以檔案許可權相關的 os.stat('graph.py').st_modeOut[9]:
33252In [10]:
#轉換成八進位制 oct(os.stat('graph.py').st_mode)Out[10]:
'0o100744'In [11]:
os.chmod('graph.py',os.stat('graph.py').st_mode | stat.S_IXUSR)In [12]:
ls -l
總用量 24
-rwxr--r-- 1 zhou zhou 0 12月 14 14:55 graph.py*
-rw-r--r-- 1 zhou zhou 0 12月 14 14:56 heap.java
-rw-r--r-- 1 zhou zhou 0 12月 14 14:56 install.sh
-rw-r--r-- 1 zhou zhou 1 12月 14 14:55 quicksort.c
-rw-r--r-- 1 zhou zhou 0 12月 14 14:56 stack.cpp
-rw-r--r-- 1 zhou zhou 17606 12月 14 18:03 複雜場景下字串處理相關問題與解決技巧.ipynb
3.如何調整字串中文字的格式¶
''' 案例:把'yyyy-mm-dd'改成'mm/dd/yyyy' 解決方案:使用正則表示式re.sub()方法做字串替換,利用正則表示式的捕獲組,捕獲每個部分內容,在替換字串中調整各個捕獲組的順序 ''' In [13]:cat /var/log/alternatives.log
update-alternatives 2018-12-10 09:40:25: run with --install /usr/share/gnome-shell/theme/gdm3.css gdm3.css /usr/share/gnome-shell/theme/ubuntu.css 10 update-alternatives 2018-12-10 09:40:33: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/firefox 40 update-alternatives 2018-12-10 09:40:33: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 update-alternatives 2018-12-10 09:42:23: run with --install /usr/bin/gstreamer-codec-install gstreamer-codec-install /usr/lib/packagekit/pk-gstreamer-install 80 update-alternatives 2018-12-10 09:43:43: run with --install /usr/bin/x-window-manager x-window-manager /usr/bin/mutter 60 --slave /usr/share/man/man1/x-window-manager.1.gz x-window-manager.1.gz /usr/share/man/man1/mutter.1.gzIn [14]:
log = open('/var/log/alternatives.log').read()In [15]:
import re #按照順序編號 print(re.sub('(\d{4})-(\d{2})-(\d{2})',r'\2/\3/\1',log))
update-alternatives 12/10/2018 09:40:25: run with --install /usr/share/gnome-shell/theme/gdm3.css gdm3.css /usr/share/gnome-shell/theme/ubuntu.css 10 update-alternatives 12/10/2018 09:40:33: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/firefox 40 update-alternatives 12/10/2018 09:40:33: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 update-alternatives 12/10/2018 09:42:23: run with --install /usr/bin/gstreamer-codec-install gstreamer-codec-install /usr/lib/packagekit/pk-gstreamer-install 80 update-alternatives 12/10/2018 09:43:43: run with --install /usr/bin/x-window-manager x-window-manager /usr/bin/mutter 60 --slave /usr/share/man/man1/x-window-manager.1.gz x-window-manager.1.gz /usr/share/man/man1/mutter.1.gzIn [16]:
print(re.sub('(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})',r'\g<month>/\g<day>/\g<year>',log))
update-alternatives 12/10/2018 09:40:25: run with --install /usr/share/gnome-shell/theme/gdm3.css gdm3.css /usr/share/gnome-shell/theme/ubuntu.css 10 update-alternatives 12/10/2018 09:40:33: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/firefox 40 update-alternatives 12/10/2018 09:40:33: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 update-alternatives 12/10/2018 09:42:23: run with --install /usr/bin/gstreamer-codec-install gstreamer-codec-install /usr/lib/packagekit/pk-gstreamer-install 80 update-alternatives 12/10/2018 09:43:43: run with --install /usr/bin/x-window-manager x-window-manager /usr/bin/mutter 60 --slave /usr/share/man/man1/x-window-manager.1.gz x-window-manager.1.gz /usr/share/man/man1/mutter.1.gz
4.如何將多個小字串拼接成一個大的字串¶
''' 一.迭代列表,連續使用'+'操作依次拼接每一個字串 二.使用str.join()方法,更加快速的拼接列表中的所有字串 ''' In [17]:s1 = 'abcdefg' s2 = '12345'In [18]:
s1 + s2Out[18]:
'abcdefg12345'In [19]:
str.__add__(s1,s2)Out[19]:
'abcdefg12345'In [20]:
s1 > s2Out[20]:
TrueIn [21]:
str.__gt__(s1,s2)Out[21]:
TrueIn [22]:
pl = ['<0112>','<32>','<1024x768>','<60>','<1>','<100.0>','<500.0>']In [23]:
s = ''In [24]:
for p in pl: s += p print(s) #存在資源浪費
<0112> <0112><32> <0112><32><1024x768> <0112><32><1024x768><60> <0112><32><1024x768><60><1> <0112><32><1024x768><60><1><100.0> <0112><32><1024x768><60><1><100.0><500.0>In [25]:
s
Out[25]:
'<0112><32><1024x768><60><1><100.0><500.0>'In [26]:
# 不存在臨時變數的浪費 "".join(pl)Out[26]:
'<0112><32><1024x768><60><1><100.0><500.0>'In [27]:
# 存在數字和字串 l = ['abc',123,45,'xyz']In [28]:
# 列表解析 ''.join([str(x) for x in l])Out[28]:
'abc12345xyz'In [29]:
# 生成器表示式,開銷比列表解析式小 ''.join(str(x) for x in l)Out[29]:
'abc12345xyz'
5.如何對字串進行左, 右, 居中對齊¶
''' 案例: { "a":100, "as":0.01, "wer":500.0, "cc":12 } 處理成: "a" :100, "as" :0.01, "wer":500.0, "cc" :12 解決方案: 1.使用字串的str.ljust(),str.rjust(),str.center()進行左右中對齊 2.使用format()方法,傳遞類似'<20','>20','^20'引數完成同樣任務 ''' In [30]:s = 'abc'In [31]:
s.ljust(20)Out[31]:
'abc 'In [32]:
s.ljust(20,'=')Out[32]:
'abc================='In [33]:
s.rjust(20)Out[33]:
' abc'In [34]:
len(s.rjust(20))Out[34]:
20In [35]:
s.center(20)Out[35]:
' abc 'In [36]:
s = 'abc'In [37]:
format(s,'<20')Out[37]:
'abc 'In [38]:
format(s,'>20')Out[38]:
' abc'In [39]:
format(s,'^20')Out[39]:
' abc 'In [40]:
d = { "a":100, "as":0.01, "wer":500.0, "cc":12 }In [41]:
d
Out[41]:
{'a': 100, 'as': 0.01, 'wer': 500.0, 'cc': 12}In [42]:
d.keys()Out[42]:
dict_keys(['a', 'as', 'wer', 'cc'])In [43]:
# 通過map找出key的長度 list(map(len,d.keys()))Out[43]:
[1, 2, 3, 2]In [44]:
max(list(map(len,d.keys())))Out[44]:
3In [45]:
w = max(list(map(len,d.keys())))In [46]:
for k in d: print(k.ljust(w),':',d[k])
a : 100 as : 0.01 wer : 500.0 cc : 12
6.如何去掉字串中不需要的字元¶
''' 案例: 1.過濾掉使用者輸入中前後多餘的空白字元:' [email protected] ' 2.過濾windows下編輯文字中的'\r':'hello world\r\n' 3.去掉文字中的unicode符號"āáǎà ōóǒò ēéěè īíǐì" 方案: 1.字串strip(),lstrip(),rstip()去掉字串兩端字元 2.刪除單個固定位置的字元,可以使用切片+拼接的方式 3.字串的replace()方法或正則表示式re.sub()刪除任意位置字元 4.字串translate()方法,可以同時刪除多種不同字元 ''' In [47]:s = ' abc 123 'In [48]:
s.strip()Out[48]:
'abc 123'In [49]:
s.lstrip()Out[49]:
'abc 123 'In [50]:
s.rstrip()Out[50]:
' abc 123'In [51]:
s = '+++abc---'In [52]:
s.strip('+-')Out[52]:
'abc'In [53]:
s = 'abc:123'In [54]:
s[:3] + s[4:]Out[54]:
'abc123'In [55]:
s = '\tabc\t123\txyz'In [56]:
s
Out[56]:
'\tabc\t123\txyz'In [57]:
# 替換單個字元 s.replace('\t','')Out[57]:
'abc123xyz'In [58]:
s = '\tabc\t123\txyz\ropt\r'In [59]:
import re # 替換多個不同字元 re.sub('[\t\r]','',s)Out[59]:
'abc123xyzopt'In [60]:
s = 'abc123def456xyz'In [61]:
a = s.maketrans('abcxyz','xyzabc')In [62]:
a
Out[62]:
{97: 120, 98: 121, 99: 122, 120: 97, 121: 98, 122: 99}In [63]:
s.translate(a)Out[63]:
'xyz123def456abc'In [64]:
t = 'abc\refg\n234\t'In [65]:
remap = { # ord返回ascii值 ord('\t'): '', ord('\n'): '', ord('\r'): None }In [66]:
t.translate(remap)Out[66]:
'abcefg234'In [67]:
import sys import unicodedata s = 'āáǎà ōóǒò ēéěè īíǐì' remap = { # ord返回ascii值 ord('\t'): '', ord('\f'): '', ord('\r'): None } # 去除\t, \f, \r a = s.translate(remap) ''' 通過使用dict.fromkeys() 方法構造一個字典,每個Unicode 和音符作為鍵,對於的值全部為None 然後使用unicodedata.normalize() 將原始輸入標準化為分解形式字元 sys.maxunicode : 給出最大Unicode程式碼點的值的整數,即1114111(十六進位制的0x10FFFF)。 unicodedata.combining:將分配給字元chr的規範組合類作為整數返回。 如果未定義組合類,則返回0。 ''' cmb_chrs = dict.fromkeys(c for c in range(sys.maxunicode) if unicodedata.combining(chr(c))) #此部分建議拆分開來理解 b = unicodedata.normalize('NFD', a) ''' 呼叫translate 函式刪除所有重音符 ''' print(