Python-正则表达式
python正则表达式
re模块提供正则表达式操作
re模块中常用方法:
-
match
-
search
-
findall
-
finditer
-
re.match(pattern, string, flags=0)
根据正则表达式pattern, 从待匹配字符串string的开头进行匹配, 如果匹配成功, 则返回正则匹配结果对象; 如果没有匹配成功, 返回None
.
import re s1 = 'hello kitty' s2 = 'kitty hello' r1 = re.match('hello', s1) print(r1) print(r1.group()) r2 = re.match('hello', s2) print(r2) # 执行结果 <_sre.SRE_Match object; span=(0, 5), match='hello'> # 这是正则匹配结果对象,不是具体的匹配值 hello None # 得到正则匹配结果对象, 可以调用正则匹配结果对象的方法或属性
调用正则匹配结果对象(match object)group方法, group参数说明
s1 = 'hello kitty haha kitty' pattern = re.compile('(hello).*?(haha)') r = re.match(pattern, s1) print(r) print(r.group()) # group中没有参数,就是默认为0,与r1.gruop(0)等价; 返回整个match的匹配结果 print(r.group(1)) # 字符串形式返回匹配的第一个括号组(子组) print(r.group(2)) # 字符串形式返回匹配的第二个括号组 print(r.groups()) # 返回所有的匹配括号组, 放在一个元组中返回 # 执行结果 <_sre.SRE_Match object; span=(0, 16), match='hello kitty haha'> hello kitty haha hello haha ('hello', 'haha')
re.search(pattern, string, flags=0)
顺序扫描 string , 寻找正则表达式 pattern 产生匹配的第一个位置, 并返回相应的正则匹配结果对象; 若string中没有任何位置能匹配该模式, 则返回 None
.
s = 'this123long456str' pattern = re.compile('\d+') r = re.search(pattern, s) print(r) print(r.group()) # 执行结果 <_sre.SRE_Match object; span=(4, 7), match='123'> # 找到符合正则表达式规则的字符串后,返回结果 123 # 找到符合规则后,不在继续向后查找匹配,所以后面符合规则的456不会返回 s = 'this123long456str' pattern = re.compile('\w+?(\d+)\w+?(\d+).*') r = re.search(pattern, s) print(r) print(r.group()) print(r.group(1)) print(r.group(2)) print(r.groups()) # 执行结果 <_sre.SRE_Match object; span=(0, 17), match='this123long456str'> this123long456str 123 456 ('123', '456')
re.findall(pattern, string, flags)
返回字符串中pattern的所有非重叠匹配项作为字符串列表. The string是从左到右扫描的, 所以匹配的内容是按照该顺序来的, 如果模式中存在一个或多个组,请返回组列表; 如果模式有多个组, 这将是一个元组列表。
说明:
-
如果pattern中不包含分组, 那么按照pattern从左到右扫描string, 符合pattern规则的, 提取出来, 加到列表中, 继续向右扫描, 遇到符合pattern规则的再加到列表中. 返回结果就是一个大的列表, 如果没有找到匹配, 则返回空列表.
-
如果pattern中包含分组, 且只有一个分组, 那么按照pattern规则匹配, 但是会把分组的匹配结果加到列表中,不是把符合pattern这个整体规则的结果加到列表中.
-
如果pattern中包含分组, 且有多个分组, 那么按照patter规则匹配, 匹配成功后, 会把每个分组的匹配结果提出来组成一个元组, 然后把这个元组加到列表中, 最终结果就是多个元组组成的列表.
# 1)不包含分组 s = 'abc 123cd 56ef' pattern = re.compile('\d+\w+') r = re.findall(pattern, s) print(r) # 执行结果 ['123cd', '56ef'] # 2)包含一个分组 s = 'abc 123cd 56ef' pattern = re.compile('\d+(\w+)') r = re.findall(pattern, s) print(r) # 执行结果 ['cd', 'ef'] # 3)包含多个分组 s = 'abc 123cd 56ef' pattern = re.compile('(\d+)(\w+)') r = re.findall(pattern, s) print(r) # 执行结果 [('123', 'cd'), ('56', 'ef')]
re.finditer(pattern, string, flags)
finditer与findall类似, 但是finditer的返回结果是一个迭代器
# 1)不包含分组 s = 'abc 123cd 56ef' pattern = re.compile('\d+\w+') r = re.finditer(pattern, s) print('type result:', type(r)) for item in r: print(item) print(item.group()) # 执行结果 type result: <class 'callable_iterator'> <_sre.SRE_Match object; span=(4, 9), match='123cd'> 123cd <_sre.SRE_Match object; span=(10, 14), match='56ef'> 56ef # 2)包含一个分组 s = 'abc 123cd 56ef' pattern = re.compile('\d+(\w+)') r = re.finditer(pattern, s) for item in r: print(item.group()) print(item.group(1)) # 执行结果 123cd cd 56ef ef # 3)包含两个分组 pattern = re.compile('(\d+)(\w+)') r = re.finditer(pattern, s) for item in r: print(item.group()) print(item.group(1)) print(item.group(2)) # 执行结果 123cd 123 cd 56ef 56 ef
re.sub(pattern, repl, string, count=0, flags=0)
将string中最左侧非重叠出现的pattern替换为repl, 返回所获得的字符串.
s = 'abc123efg45hh' pattern = re.compile('\d+') r = re.sub(pattern, '-', s) print(r) # 执行结果 abc-efg-hh # 可以指定替换次数 s = 'abc123efg45hh' pattern = re.compile('\d+') r = re.sub(pattern, '-', s, count=1) print(r) # 执行结果 abc-efg45hh
其他正则表达式语法
(?:...)
一个正则括号的不捕获版本. 如果pattern中包含分组, 那么pattern整体匹配后, 会把分组的匹配值作为结果返回, 就是分组的优先级高. 如果我只是想把分组当做普通的分组处理, 不把它的匹配值作为结果返回, 而是返回pattern整体匹配值的结果, 那么就可以在分组内部加上?:
s = 'abc123efg45hh' pattern = re.compile('\w+?\d+') r = re.findall(pattern, s) print(r) # 执行结果 ['abc123', 'efg45'] s = 'abc123efg45hh' pattern = re.compile('\w+?(\d+)') r = re.findall(pattern, s) print(r) # 执行结果 ['123', '45'] # 优先返回分组结果 s = 'abc123efg45hh' pattern = re.compile('\w+?(?:\d+)') r = re.findall(pattern, s) print(r) # 执行结果 ['abc123', 'efg45'] # 把pattern内的分组当做普通分组处理, 返回pattern整体匹配值
(?P<name>...)
和正则括号相似, 但是这个组匹配到的子字符串可以通过符号组名称name进行访问.组名称必须是有效的Python标识符, 并且每个组名称在正则表达式中只能被定义一次(注:组名必须唯一).一个符号组也是一个带编号的组, 就好像这个组没有被命名一样.(注:除了原有的编号外再指定一个额外的别名).
s = '<a>This is a link</a>' pattern = re.compile('<(?P<tag1>\w+)>.*?<(?P<tag2>/\w+)>') r = re.search(pattern, s) print(r) print(r.group()) print(r.group(1)) print(r.group(2)) print(r.group('tag1')) print(r.group('tag2')) # 执行结果 # 就是为分组指定了名称,可以根据名称去访问这个组的匹配值 <_sre.SRE_Match object; span=(0, 21), match='<a>This is a link</a>'> <a>This is a link</a> a /a a /a
(?P=name)
对指定组的反向引用;它匹配任何名为name的早期组匹配的文本。
s = '<a>This is a link</a>' pattern = re.compile('<(?P<tag1>\w+)>.*?</(?P=tag1)>') # ?P=tag1中匹配的内容必须与之前组名tag1匹配的完全一致 r = re.search(pattern, s) print(r) print(r.group()) print(r.group('tag1')) # 执行结果 <_sre.SRE_Match object; span=(0, 21), match='<a>This is a link</a>'> <a>This is a link</a> a
以上就是关于python re模块常用方法的总结, 欢迎补充.