Python-正则表达式

python正则表达式

re模块提供正则表达式操作

re模块中常用方法:

  • match

  • search

  • findall

  • finditer

  • sub

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模块常用方法的总结, 欢迎补充.

 

原文地址:https://www.cnblogs.com/gandoufu/p/9457386.html