一. 如何判断字符串a是否以字符串b开头或结尾?
实际案列
某文件系统目录下有一系列文件:
quicksort.c
graph.py
heap.java
install.sh
stack.cpp
编写程序给其中所有.sh文件 和 .py文件加上用户可执行权限
解决方案
使用str.startswith() 和 str.endswith() 方法
(注意: 多个匹配时参数使用元组)
要用到的python代码技术点
s = os.stat('b.py') # 获取文件状态的 对象
# ls -l b.py
# -rw-r--r-- 1 cannon cannon 0 Mar 12 14:06 b.py
oct(s.st_mode) # 0o100644 权限的八进制 644
s.st_mode | 0o100 # 0o100744
os.chmod('b.py', s.st_mode | 0o100) # 修改b.py可执行权限
代码实现
import stat, os
for fn in os.listdir():
if fn.endswith('.py', '.sh'):
fs = os.stat(fn)
os.chmod(fn, fs.st_mode | stat.S_IXUSR)
二. 如何调整字符串中文本的格式
实际案例
某软件的log文件, 其中的日期格式为'yyyy-mm-dd':
2016-05-21 10:39:26 statys unpacked python3-pip:all
2016-05-23 10:49:26 status half-configured python3
....
我们想要把其中日期改为美国日期的格式 'mm/dd/yyyy'
即 '2016-05-23' => '05/23/2016', 应该如何处理?
解决方案
使用正则表达式re.sub() 方法 做字符串替换, 利用正则表达式的组, 捕获每个部分内容, 在替换字符串中调整各个捕获组的顺序
log = "2016-05-21 10:39:26 statys unpacked python3-pip:all
2016-05-23 10:49:26 status half-configured python3"
import re
re.sub('(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', log)
# 或者可以给组命名
re.sub('(?P<d>\d{4})-(?P<m>\d{2})-(?P<y>\d{2})', r'\g<m>/\g<d>/\g<y>', log)
三. 如何将多个小字符串拼接成一个大的字符串
实际案例
在设计某网络程序时, 我们自定义了一个基于UDP的网络协议
按照固定次序想服务器传递一系列参数:
hwDetect: "<0112>"
gxDepthBits: "<32>"
gxResolution: "<1024x768>"
gxRefresh: "<60>"
fullAlpha: "<1>"
lodDist: "<100.0>"
DistCull: "<500.0>"
在程序中我们将各个参数按次序手机到列表中:
["<0112>", "<32>", "<1024x768>", "<60>", "<1>", "<100.0>", "<500.0>"]
最终我们要把各个参数拼接成一个数据报进行发送
"<0112><32><1024x768><60><1><100.0><500.0>"
解决方案
使用str.join()方法, 快速拼接列表中所有字符串
l = ["<0112>", "<32>", "<1024x768>", "<60>", "<1>", "<100.0>", "<500.0>"]
''.join(l)
四. 如何对字符串进行左右 居中对齐
实际案列
某个字典存储了一系列属性值
{
"lodDist": 100.0,
"SmallCull": 0.04,
"DistCull": 500.0,
"trilinear": 40,
"farclip":477
}
在程序中, 我们想以工整的格式将其内容输出, 如何处理?
SmallCull: 0.04
farclip : 477
lodDist : 100.0
DistCull : 500.0
trilinear: 40
解决方案
方法一: 使用字符串的str.ljust(), str.rjust(), str.center() 进行左 右 居中对齐
s = 'abc'
s.ljust(10)
# 'abc '
# 如果传入 2 比s的长度都小 不会做任何处理
s.ljust(2)
# 'abc'
# 指定填充的字符, 只能指定一种字符
s.ljust(*10)
# 'abc*******'
方法二: 使用format()方法, 触底类似'<20','>20', '^20'参数完成同样任务
# 左对齐
format(s, '<10')
# 'abc '
# 右对齐
format(s, '>10')
# ' abc'
# 居中对齐
format(s, '^10')
# ' abc '
# 空余用*填充
format(s, '*^10')
# '***abc****'
# 对于数字的用法
# + 表示无论征正负 总输出符号
format(10, '+')
# '+10'
format(-10, '+')
# '-10'
# = 表示符号在左 数字在右
format(567, '0=+10')
# '+000000567'
解题代码
d = {
"lodDist": 100.0,
"SmallCull": 0.04,
"DistCull": 500.0,
"trilinear": 40,
"farclip": 477
}
w = max(map(len, d.keys())) # key中最长的 作为对齐的宽度
for k, v in d.items():
print(k.ljust(w), ':', v)
五. 如何去掉字符串中不需要的字符
实际案列
1. 过滤掉用户输入中前后多余的空白字符:
' nick2008@gmail.com '
2. 过滤某windows 下编辑文本中的'\r':
'hello world\r\n'
3. 去掉文本中的unicode组合符号(音调):
'ní hǎo, chīfàn'
解决方法
方法一. 字符串strip(), lstrip(), rstrip() 方法去掉字符串两端字符
s = '\t =+-*cannon@qq.com==== \t' # 空白字符 包含\t
s.strip() # 两端空白字符都去掉
s.lstrip() # 去掉左边的空白字符
s.rstrip() # 去掉右边的空白字符
s.strip('=+-*') # 两端+-=*都去掉
方法二. 删除单个固定位置的字符, 可以使用切片 + 拼接的方式
s2 = 'abc:1234'
s2[:3] + s2[4:]
方法三. 字符串的replace()方法或正则表达式re.sub()删除任意子串
s3 = ' abc xyz ' # strip 无法去掉中间的空格
s3.replace(' ', '')
s3 = '\t abc \t xyz \n' # replace就比较麻烦了
import re
re.sub('[ \t\n]+', '', s3)
re.sub('\s+', '', s3) # \s 表示空白符号
方法四. 字符串的translate()方法, 可以同时删除多种不同字符
s = 'abc1234xyz'
# 如何把a变为X b变为Y
s.translate({ord('a'): 'X', ord('b'): 'Y'}) # 映射表的key必须是unicode值 value可以是unicode值也可以是字符
# 也可以利用makestrans获取unicode映射表
s.maketrans('ab', 'XY') # 要一一对应
# {97:88, 98:89}
s.translate(s.maketrans('ab', 'XY'))
# 删除s中的a
s.translate({ord('a'): None})
# 去除拼音的音调
s4 = 'ní hǎo, chīfàn'
print(s4.translate(s4.maketrans('íǎīà', 'iaia')))
# 'ni hao, chifan'
六. 分割字符串问题
实际案例
已知字符串"ab;cd|efg|hi,jk1|mn\topq;rst,uvw\txyz",
其中的',' ';' '|' '\t' 都是分割符,如何处理?
方法1、 连续使用str.split
s = "ab;cd|efg|hi,jk1|mn\topq;rst,uvw\txyz"
def my_split(s, seps):
res = [s]
for sep in seps:
t = []
map(lambda ss: t.extend(ss.split(sep)), res)
res = t
return res
print(my_split(s, ',;|\t'))
结果
['ab', 'cd', 'efg', 'hi', 'jk1', 'mn', 'opq', 'rst', 'uvw', 'xyz']
或者通过reduce
from functools import reduce
my_split2 = lambda s, seps: reduce(lambda l, sep: sum(map(lambda ss: ss.split(sep), l), []), seps, [s])
print(my_split2(s, ',;|\t'))
结果
['ab', 'cd', 'efg', 'hi', 'jk1', 'mn', 'opq', 'rst', 'uvw', 'xyz']
此方法因为不方便阅读,所以不推荐
方法2、 正则表达式re.split方法(推荐)
import re
print(re.split('[;,|\t]+', s))
结果
['ab', 'cd', 'efg', 'hi', 'jk1', 'mn', 'opq', 'rst', 'uvw', 'xyz']