(内容包括正则表达式,re模块等)
1 正则表达式
1.1 正则表达式介绍
正则表达式也叫RE (Regular Expression),是一个特殊的字符序列,描述了一种字符串匹配的模式(pattern),为高级文本模式匹配,以及搜索-替代等功能提供了基础。它能帮助你方便的检查一个字符串是否与某种模式匹配,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。正则表达式利用描述性语言来给字符串定一个规则,符合规则就认为匹配成功。
正则表达式的英文名叫Regular Expression,也被缩写为regex,regexp。是开发Unix二人组之一的肯·汤普森所首先使用(另一位开发Unix的是C语言之父丹尼斯里奇,肯汤普森是Go语言之父)。perl语言的PCRE对正则表达式的发展起到了决定性的作用。各种高级语言和shell都支持正则表达式。
1.2 正则表达式的分类
正则表达式可以分成BRE(基本正则表达式),ERE(扩展正则表达式)和PCRE和变种(高级语言专用正则表达式,由perl语言演变而来)
1.3 正则表达式的运用
利用正则表达式可以对文本信息进行大致匹配,再用python的字符串功能把所提取的字符串进行再处理,可以发挥正则表达式的作用。但是需要注意的是,正则表达式只能做一些自己能做到的匹配,但是没法做所有的准确匹配。而且正则表达式就是为了简化而设计的,写的太复杂没有必要,不宜过于复杂。
举个例子,比如电话号码,可以对11位1开头的数字进行匹配,但你不知道是否确有其号,166开头的手机是有的,但不是16600000000至16699999999的手机号都有,可以是空号。
1.3.1 元字符 metacharacter
元字符是用来描述你想匹配的字符的字符。每一个元字符都可以匹配一个实际字符,不同的元字符可以匹配不同种类的字符。
下面提供一张表格列举这些元字符:
除此以外,用于匹配的元字符还有常规的任何数字字母标点汉字等。但值得注意的是,每个元字符只能匹配一个实际字符。
需要注意的是,不能随便加空格。 另外如果能不用取反,尽量不用,因为取反可能会包含进一些本来不想要的东西。
1.3.2 重复
上文说到了元字符只能匹配一个实际字符,遇到长篇大论需要进行字符操作,我们就会用到重复。 使用重复可以扩展元字符的功能,将多个具有一定规律的字符串利用一定的规律进行匹配。将需要重复的字符写在元字符的后面可以对元字符出现的次数进行规定,从而让元字符重复,这样可以使用最少的代码完成最有效率的匹配。
下面提供一张表格列举常用重复字符:
需要注意的是,对于重复的匹配规则,是贪婪的。
1.3.3 贪婪和非贪婪
所谓贪婪,指的是在同样满足条件的情况下,正则表达式重复符的匹配会使被匹配的内容尽可能的长。而非贪婪则是尽可能的短。
举个简单的例子来说,一个字符串'wddddddadd',如果你用正则表达式'w.+d'来进行匹配,就会匹配上一整个字符串,这就叫贪婪。同样是这个字符串,你用正则表达式'w.+?d'来进行匹配,你就会匹配到'wdd',这就叫做非贪婪。
在Python中,重复被默认为是贪婪的,如果需要非贪婪的重复,可以在重复符的右边加上?,这样就会变成非贪婪。
1.3.4 分组/捕获
正则表达式中的小括号,可以用作改变优先级和分组。如果想让小括号变为其自己的含义,需要使用转义字符\(\)来匹配小括号,在中括号中的小括号就是普通小括号,没有分组/捕获的意思。
具体来说,正则表达式中的小括号可以对被括住的内容进行分组。
分组的引用:用\num来表示被捕获字符串(注意是这个字符串,不是正则表达式)。只能匹配和分组同样的字符串,不能匹配仅正则表达式相同的字符串。
举个例子:'abcd_dcba',我用'(\w+)_\1'什么都匹配不到,这个正则表达式只能匹配'abcd_abcd',因为在这里,这个正则表达式等价于'(\w+)_abcd'。
另外,使用分组时要注意,分组的引用下标从1开始,0时全集,匹配的是整个正则表达式。
还有,(?P<name>exp)表示将这个分组取一个别名,别名为name,可以对分组多的正则表达式使用。
1.3.5 模式
正则表达式一共把需要读取的文本分成了若干种模式,常用的模式如下:
请注意:
- 默认模式下,不管有几行,都当作一行,但是元字符.不能匹配换行符,且只有一个行首^一个行尾$;
- 单行模式下,不管有几行,都当作一行,但是元字符.能匹配换行符,也就是.+可以把整个文本都匹配上,且只有一个行首^一个行尾$;
- 多行模式下,有几行就算几行,元字符.不能匹配换行符,每个换行符的后面和前面都有一个行首^和一个行尾$。
各种模式不互斥,如果你既想用单行模式又想用多行模式(.能穿透换行符,每行首用^匹配,行尾用$匹配),可以用位或符号|来表示。
举个例子,re.compile(pattern,flag=re.M|re.S),就可以用单行模式与多行模式。
1.4 断言
所谓断言,就是把正则表达式的匹配加一个条件,如果前面或后面含有条件中的内容,那么,就把中间的字符串取出来。根据字符串的(左边/右边)(含有/不含有)两个条件,一共有4种断言手法。
2 Python中的正则表达式——RE模块
re是python的内置库,需要导入模块。使用import re导入。
2.1 编译
s = re.compile(pattern,flag = 0) 第一个参数是正则表达式,第二个默认参数是编译模式,0是默认模式。返回值是一个被编译过的正则表达式。
2.2 单次匹配
可以使用match方法对文本进行从文本首字符的匹配:
m = re.match(pattern,string,flag=0) ,第一个参数是正则表达式,第二个是待匹配文本,第三个是模式。如果匹配成功,返回一个match对象,当中包括span的始末位置和match值,如果匹配不成功,返回None。
另一个方法是fullmatch(),参数和match一样,但是只有整个文本和正则表达式完全匹配才会返回match对象。
2.3 多次匹配
用findall和finditer方法可以对文本进行多次查找。
s = re.findall(pattern, string, flags=0) 第一个参数是正则表达式,第二个是待匹配文本,第三个是模式。如果匹配成功,返回一个列表,当中的元素是匹配成功的字符串,如果匹配不成功,返回None。
s =re.finditer(pattern, string, flags=0) 它和findall不同之处在于,finditer在匹配成功时,返回一个迭代器,遍历迭代器,其中是匹配成功的一个个match对象,如果匹配不成功,返回空迭代器。
2.4 替换
用sub和subn可以对文本进行替换。
s = re.sub(pattern,'replacement',string,times) 第一个参数是正则表达式,第二个是替换为什么字符内容,第三个是原文本,第四个是替换次数,默认都替换。返回一个被替换的新文本。过程中,原文本数值不变。
subn的用法和sub相同,返回一个元组,元组的第一个元素是被替换的新文本,第二个元素是替换次数。
在上述re模块的操作中,字符串是重要的参数,在进行字符串参数书写时,建议使用前缀r,也就是r'string',以避免一些不小心的转义字符导致的二进制ASCII码。比如用'\1'时,系统可能会判定你写的不是分组的引用,而是ASCII码的1号字符。
2.5 分组
使用re.group(num)可以把你分出的组的内容进行返回。
2.6 split
在内置函数中的split()方法可以将字符串分隔为多个字符串元素的列表进行返回,默认参数情况下是以正则表达式的\s+进行分割,然而,内置方法不能直接用正则表达式进行更加多样的分割。
s = re.split(pattern,string)允许利用正则表达式将原文本进行切割,返回值和内置函数split的返回值相同。
如果您觉得Tc写得不错或者不好,欢迎批评✖或点赞👍。