Hi! 大家好,我是Eric,这次教大家Python的字串处理(string processing)!

■ 字串处理(string processing)
■ 定义字串
x = "abc" # 可用双引号定义x = 'abc' # 也可用单引号定义x = """ # 可用三重引号跨行定义字串abcxyz"""
■ 简易字串操作
产生字串pi=3.14 str(pi)"The value of pi is " + str(pi)
字串格式化:大小写转换fox = "bHkloY"fox.upper() #全部字元转成大写fox.lower() #全部字元转成小写fox.title() #首字转成大写fox.capitalize #每个字词的首字转成大写fox.swapacase #将大小写颠倒
字串格式化:新增和删除空格line=" adf " line.strip() #删除前后的空格line.rstrip() #删除右边的空格line.lstrip() #删除左边的空格 num="00000345"num.strip("0") #删除特定字元 line = "this is the content"line.center(30) #产生一定数量的空格,并中心对齐一个给定的字串line.ljust(30) #产生一定长度的空格并左对齐line.rjust(30) #产生一定长度的空格并右对齐"345".rjust(10,"0") #能以任意字元填充空格"345".zfill(10) #在左边填充一定数量的0
查询和替换⼦字串line = 'the quick brown fox jumped over a lazy dog'line.find('fox') #查询子字串在字串中出现的索引,若搜寻不到子字串,会回传-1line.index('fox') #查询子字串在字串中出现的索引,若搜寻不到子字串,会回传ValueErrorline.rfind('fox') #从尾部往前查询子字串在字串中出现的索引 line.endswith('dog') #检查字串尾部的子字串linie.startswith('fox') #检查字串头部的子字串 line.replace('brown','red') #以第2个参数替换子字串
拆分和分割字串line.partition('fox')#partition()会回传3个tuple,分别是:目标子字串之前的子字串、目标子字串、目标子字串之后的子字串line.rpartition('fox') #rpartition()从右向左搜寻字串line.split() #split()预设以空白作为分割依据,回传所有单字 haiku = """matsushima-yaaah matsushima-yamatsushima-ya""" haiku.splitlines() #splitlines()对换行符号进行分割 '--'.join(['1', '2', '3']) #撤销split()的结果,用分割依据再组成一个字串print("\n".join(['matsushima-ya', 'aah matsushima-ya', #常见的用法是用换行符号还原成原字串'matsushima-ya']))
■ 格式化字串
格式化字串pi=3.14"The value of pi is {}".format(pi) #以{}代表将要插入字串格式化后的值"""First letter: {0}. Last letter: {1}.""" .format('A', 'Z')#{}中设定数字代表要插入的参数的索引"""First letter: {first}. Last letter: {last}.""" .format(last='Z', first='A')#若{}中包括了一个字串,则可以名称指定要插入的值"pi = {0:.3f}".format(pi)#数字的插入,0代表要插入的参数的索引,:代表后面要跟着格式化的程式码,.3f代表需要的精度资讯,小数点后保留3位小数的浮点数
■ 使用正则表达式灵活地匹配字串模式
正则表达式。Python ⽀援正则表达式的介⾯存放在内建的 re 模组中line = 'the quick brown fox jumped over a lazy dog'
正则表达式的spilt()我们编译一个正则表达式,然后用它来分割字符串,和Python的spilt()一样,返回了一个包含所有空格之间的子字 串的列表。
import reregex = re.compile('\s+') regex.split(line) #\s是一个特殊的字元,匹配所有空白字元(包含空格、TAB字元、换行符号等),+指名它在实体出现一次或多次。
正则表达式的match(),会回传一个字串的开头是否匹配了模式串for s in [" ", "abc ", " abc"]: if regex.match(s): print(repr(s), "matches") else: print(repr(s), "does not match")
正则表示式的regex.search(),类似str.index()、str.find(),会搜寻子字串在字串中的索引line = 'the quick brown fox jumped over a lazy dog'regex = re.compile('fox')match = regex.search(line)match.start()
正则表达式的regex.sub(),类似str.replace(),会以第1个参数替换子字串regex.sub('BEAR', line)
■ 一个更複杂的例子
既然使用原本的方法不是更为直觉更简单吗?为什么要用比较複杂的正则表达式呢?因为正则表达式的优点不只是灵活性高而已。我们来想「匹配电子邮件地址」的问题吧,这边示範的只是简单的例子,无法用于实作上
text = "To email Guido, try guido@python.org or the older address "\ "guido@google.com."email = re.compile('\w+@\w+\.[a-z]{3}')email.findall(text)#我们可以进行进一步的操作,像是把电子邮件地址换成其他的字元串,达到保护个资的作用email.sub('--@--.--', text)
正则表达式的语法基础
简单的字串直接匹配
regex = re.compile('ion')regex.findall('Great Expectations')
有一些字元在正则表达式中是有特殊意义的,使用上需要用反斜线()跳脱他们,所以在正则表达式中. ^ $ * + ? { } [ ] \ | ( ) regex = re.compile(r'\$') #r表明是一个原始字串(raw string),\代表特殊的字元regex.findall("the cost is $20") print('a\tb\tc') #\t是代表tab作用 print(r'a\tb\tc') #在原始字串中不会作用
以下为常见的特殊字元,详参(https://docs.python.org/3/library/re.html#re-syntax)regex = re.compile('[aeiou]')regex.split('consequential')
可以短横线(-)指定字符範围,如[a-z]匹配任意小写字母,[1-3]匹配任意数字1、2、3regex = re.compile('[A-Z][0-9]')regex.findall('1043879, G2, H6')
若想要匹配三个字母或三个数字的字串,一般可用\w\w\w,但更具体的语法可用{数字}regex = re.compile(r'\w{3}')regex.findall('The quick brown fox')
另外,也可使用一些标记来匹配任意数量的重複字符,如+会匹配前面字元出现1或多次重複的情形regex = re.compile(r'\w+')regex.findall('The quick brown fox')
下面整理了一些正则表达式重要标记(字元为用''括起来的符号,如第一行字元为?)email = re.compile(r'\w+@\w+\.[a-z]{3}')
接着,我们使用[],就能够匹配任意字母或数字或句号email2 = re.compile(r'[\w.]+@\w+\.[a-z]{3}')email2.findall('barack.obama@whitehouse.gov')
我们可再加上()进行分组提取email3 = re.compile(r'([\w.]+)@(\w+)\.([a-z]{3})')text = "To email Guido, try guido@python.org or the older address "\"guido@google.com."email3.findall(text)
可再进一步使用?P给提取的组命名email4 = re.compile(r'(?P<user>[\w.]+)@(?P<domain>\w+)'\ '.(?P<suffix>[a-z]{3})')match = email4.match('guido@python.org')match.groupdict()
■ Refer to《Python 旋风之旅,[正体中文]Will保哥》的第15章