1. 程式人生 > >Python複雜場景下字串處理相關問題與解決技巧

Python複雜場景下字串處理相關問題與解決技巧

 

1.如何拆分含有多種分隔符的字串

''' 實際案例: 我們要把某個字串依據分隔符號拆分不同的欄位,該字串包含多種不同的分隔符,例如: s=’ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz’,其中<,>, <;>, <|>, <\t>都是分隔符號,如何處理? 解決方案: 1.連續使用str.split(),每一次處理一種分隔符號; 2.使用正則表示式的re.split(),一次性拆分字串。 ''' In [1]:
#解決方案1.連續使用str.split(),每一次處理一種分隔符號;
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]
In [2]:
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']
In [3]:
#解決方案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,stat
In [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]:
True
In [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_mode
Out[9]:
33252
In [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.gz
In [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.gz

In [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 + s2
Out[18]:
'abcdefg12345'
In [19]:
str.__add__(s1,s2)
Out[19]:
'abcdefg12345'
In [20]:
s1 > s2
Out[20]:
True
In [21]:
str.__gt__(s1,s2)
Out[21]:
True
In [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]:
20
In [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]:
3
In [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(