Python正则表达式
Python正则表达式
一、简介
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
究其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言。
它内嵌在python中,通过re模块实现。
正则表达式模块被编译成一系列的字节码,然后由用C编写的匹配引擎执行。
二、字符匹配(普通字符,元字符):
普通字符:大多数字符和字母都会和自身匹配
# 首先导入re模块 >>>import re # 去字符串里面把所有匹配到的结果通过一个列表的形式全部返回给我 >>> re.findall('alex','alexfeaedfadfx') [alex] # 普通字符串的匹配
元字符:. ^ $ * + ? {} [] | () \
"." 除换行符以外任何一个字符
>>> re.findall('al.x','alqxqqqqqqq') [alqx]
"^" 起始位置匹配
>>> re.findall('^al.x','alxxqqqqqqq') [alxx]
"$" 结尾位置匹配
>>> re.findall('al.x$','qqqqqqqalxx') [alxx]
"?" 匹配0次或者1次
>>> re.findall('al.?x','qqqqqqqqalexqqqqqqq') [alex]
"*" 匹配0到多个字符
>>> re.findall('al.*x','alqqqqqqqx') [alqqqqqqqx]
"+" 匹配1到多次字符
# 如果中间没有字符串则匹配不到 >> re.findall('al.+x','qqqqqalxqqqqq') []
"?" 匹配0到1次字符
>>> re.findall('al.?x','qqqqqalxxqqqqq') [alxx]
"{}" 匹配固定数
# 匹配3次 >>> re.findall('^al.{3}x','qqqqqalqqqxqqqqq') [alqqqx] # 匹配3到5次 >>> re.findall('^al.{3,5}x','qqqqqalqqqqxqqqqq') [alqqqqx]
注:{1,}这样表示1到多次,{,9}这样表示0到9次
"[]" 对应的位置可以是字符集中任意字符
>>> re.findall('a[cd]b','acb') ['acb'] >>> re.findall('a[cd]b','adb') ['adb'] >>> re.findall('a[cd]b','acdb') [] >>> re.findall('a[cd]+b','adcb') ['adcb']
注:在中括号中之前介绍的元字符不再有特殊意义,除了"^","-","\"有特殊意义
"^" 表示非的意思
>>> re.findall('al[^f]x','qqqqalfxppppp') []
"-" 表示一个范围
[1-9] 表示1到9
[a-z] 表示a-z
>>> re.findall('al[a-z]x','qqqqalxxppppp') [alxx]
"\" 后面加上元字符则取消元字符功能
"\"后面加普通字符实现特殊的功能
- \d 匹配任何十进制数:它相当于[0-9]
- \D 匹配任何非数字字符:它相当于[^0-9]
- \s 匹配任何空字符:它相当于[\t\n\r\f\v]
- \S 匹配任何非空字符:它相当于[^\t\n\r\f\v]
- \w 匹配任何字母数字字符:它相当于[a-zA-Z0-9_]
- \W 匹配任何非字母数字字符:它相当于[^a-zA-Z0-9_]
- \b 匹配一个单词边界,也就是指单词和空格间的位置。匹配单词边界(包括开始和结束),这里的"单词",是指连续的字母、数字下划线组成的字符串。
注意,\b的定义是\w和\W的交界,这是个零宽界定符(zero-width assertions)只用以匹配单词的词首和词尾。单词被定义为一个字母数字序列,因此词尾就是用空白符或非字母数字符来表示的。
三、函数
re.match函数
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
函数用法:
re.match(pattern, string, flags=0)
函数的参数说明:
- pattern匹配的正则表达式
- string要匹配的字符串。
- flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
- group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
- groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
# 返回match的object的结果,通过group返回被RE匹配的字符串 obj = re.match('com','comwwww.runcomobb') print(obj) # 输出 <_sre.SRE_Match object; span=(0, 3), match='com'> obj = re.match('com','comwwww.runcomobb').group() print(obj) # 输出 com
除了group还有什么呢:
- start() 返回匹配开始的位置
- end() 返回匹配结束的位置
- span() 返回一个元组包含匹配(开始,结束)的位置
obj = re.match('com','comwwww.runcomobb').span() print(obj) # 输出 (0, 3)
re.search函数
re.search 扫描整个字符串并返回第一个成功的匹配。
函数用法:
re.search(pattern, string, flags=0)
re.search与re.match用法看似差不多区别在于,re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
obj = re.search('com','wwww.runcomobb') print(obj) # 输出 <_sre.SRE_Match object; span=(8, 11), match='com'> obj = re.search('com','wwww.runcomobb').group() print(obj) # 输出 com
re.findall函数
re.findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;空的匹配也会包含在结果中。
函数用法:
findall(pattern, string, flags=0)
re.sub函数
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
函数语法:
re.sub(pattern, repl, string, count=0, flags=0)
函数的参数说明:
- pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
# 匹配替换 print(re.sub("g.t", "have", "I get A, I got B, I gut C")) # 输出 I have A, I have B, I have C # 匹配替换2次 print(re.sub("g.t", "have", "I get A, I got B, I gut C",2)) # 输出 I have A, I have B, I gut C # 匹配替换,并打印次数 print(re.subn("g.t", "have", "I get A, I got B, I gut C")) # 输出 ('I have A, I have B, I have C', 3)
re.split函数
re.split,根据正则匹配分割字符串
函数语法:
split(pattern, string, maxsplit=0, flags=0)
函数的参数说明:
- pattern: 正则模型
- string : 要匹配的字符串
- maxsplit:指定分割个数
- flags : 匹配模式
print(re.split('\d+','one1two2three3four4')) # 输出 ['one', 'two', 'three', 'four', '']
re.compile函数
这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。第二个参数flag匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I |re.M
可以把正则表达式编译成一个正则表达式的对象。可以把那些经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率。
函数语法:
re.compile(strPattern[, flag])
正则表达式修饰符 - 可选标志:
- re.I 使匹配对大小写不敏感
- re.L 做本地化识别(locale-aware)匹配
- re.M 多行匹配,影响 ^ 和 $
- re.S 使 . 匹配包括换行在内的所有字符
- re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
- re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
text = "Bourbon is a handsome boy, he is cool, clever, and so on..." # 查找所有包含'our'的单词 regex = re.compile(r'\w*our\w*') print(regex.findall(text)) # 输出 ['Bourbon']
*re.finditer(pattern, string[, flags]):
和re.findall的功能一样,区别在于finditer返回的是iter的对象,我们通过下面的例子来感受一下:
import re obj = re.finditer(r'\d+','one1two2three3four4') print(obj) # 输出 <callable_iterator object at 0x0000000000B5DB70> for i in obj: print(i.group()) # 输出 1 2 3 4 ------------------------------------------------------------------------ # 当然也可以写成这样,利用上面所学到的compile函数 pattern = re.compile(r'\d+') for i in re.finditer(pattern, 'one1two2three3four4'): print(i.group()) # 输出 1 2 3 4
四、分组
去已经匹配到的数据中再提取数据
# 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来) r = re.match("h(\w+).*(?P<name>\d)$", origin) print(r.group()) # 获取匹配到的所有结果 print(r.groups()) # 获取模型中匹配到的分组结果 print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组 r = re.search("a(\w+).*(?P<name>\d)$", origin) print(r.group()) # 获取匹配到的所有结果 print(r.groups()) # 获取模型中匹配到的分组结果 print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组 origin = "hello alex bcd abcd lge acd 19" r = re.findall("a((\w*)c)(d)", origin) print(r) origin = "hello alex bcd alex lge alex acd 19" r1 = re.split("(alex)", origin, 1) print(r1) r2 = re.split("(al(ex))", origin, 1) print(r2)