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.过滤掉用户输入中前后多余的空白字符:' hello@qq.com ' 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(b.translate(cmb_chrs))
 
aaaa oooo eeee iiii
posted @ 2018-12-14 18:03  下了一场大雨  阅读(264)  评论(0编辑  收藏  举报