一、在python中, 使用正则表达式, 需要导入re模块
代码语言:javascript复制import re
二、普通字符匹配, 使用findall
代码语言:javascript复制1 #字符匹配, 普通字符
2 #findall: 返回所有满足条件的列表集合
3 r = re.findall("alex", "afdafalexfqerqwrqwalexo")
4 print(r)
返回结果:
代码语言:javascript复制['alex', 'alex']
三、元字符 常用的元字符如下:
代码语言:javascript复制. ^ $ * ? { } [ ] | ( )
a) . 的用法
代码语言:javascript复制# . : 匹配的是除了换行符以外的任意字符, 一个点代表一个字符
print( re.findall( "lxl.l", "fqewruolxlwlqwelxlxl" ) )
print( re.findall( "lxl..l", "fqewruolxlewlqwelxlxl" ) )
执行结果
代码语言:javascript复制['lxlwl', 'lxlxl']
b) ^的用法
代码语言:javascript复制# ^:以**开始的字符串
print( re.findall( "^lxl", "lxlqrqreqlxlasss" ) )
执行结果
代码语言:javascript复制['lxlewl']
c) $的用法
代码语言:javascript复制# $:以**结尾的字符串
print( re.findall( "lxl$", "rqreqlxlassslxl" ) )
执行结果
代码语言:javascript复制['lxl']
d) * 的用法
代码语言:javascript复制print( "=== *: 匹配前面的字符出现0个或多个字符 (贪婪匹配) =====" )
print( re.findall( "lxl*", "afdafdlxl" ) )
print( re.findall( "lxl*", "afdafdlxlaaa" ) )
print( re.findall( "lxl*", "afdafdlxlllllllsvblxbbblxl" ) )
执行结果:
代码语言:javascript复制['lxl']
['lxl']
['lxlllllll', 'lx', 'lxl']
e) 的用法
代码语言:javascript复制print( "=== : 匹配前面的字符出现1个或多个字符 (贪婪匹配) =====" )
print( re.findall( "lxl ", "afdafdlxaaaalxlllll" ) )
print( re.findall( "lxl ", "afdafdlxlaaa" ) )
print( re.findall( "lxl ", "afdafdlxlllllllsvblxbbblxl" ) )
执行结果:
代码语言:javascript复制['lxlllll']
['lxl']
['lxlllllll', 'lxl']
f) ? 的用法
代码语言:javascript复制print( "=== ?: 匹配前面的字符出现0个或1个字符(贪婪匹配) =====" )
print( re.findall( "lxl?", "afdafdlxlaaaalxlllll" ) )
print( re.findall( "lxl?", "afdafdlx" ) )
print( re.findall( "lxl?", "afdafdlxlllllllsvblxbbblxl" ) )
执行结果:
代码语言:javascript复制['lxl', 'lxl']
['lx']
['lxl', 'lx', 'lxl']
g) 的用法
代码语言:javascript复制print( "=== : a. 反斜杠后面跟元字符,去除特殊功能. "
" b. 反斜杠后面跟普通字符, 实现特殊功能 "
" c. 引用序号对应的组所匹配的字符串"
"=====" )
'''
d: 匹配任何十进制数, 他相当于使用字符集[0-9]
D: 匹配任何非数字字符, 他相当于使用字符集[^0-9]
s: 匹配任何空白字符, 他相当于[ tnrfv]
S: 匹配任何非空白字符, 它相当于 [^ tnrfv]
w: 匹配任何字母数字字符, 相当于 [a-zA-Z1-9_]
W: 匹配任何非字母数字字符, 相当于[^a-zA-Z1-9_]
b: 匹配一个单词边界, 也就是单词和空格间的位置
'''
print( re.findall( "d", "a2ff3a,aaa^lx3$lll6sll" ) )
print( re.findall( "DD", "a2ff3a,aaa^lx3$lll6sll" ) )
print( re.findall( "w", "a2ff3a,aaa^lx3$lll6sll" ) )
print( re.findall( "W", "a2ff3a,aaa^lx3$lll6sll" ) )
print( re.findall( "s", "a2ff3a, aaa^lx3$lll6sll" ) )
print( re.findall( r"babcb", " abc sfasfqerqwrfasf" ) )
print( "====== c. 引用序号对应的组所匹配的字符串 =======" )
# 分析: 第一个组是alex,第二组是eric, 然后后面接com. 2表示在这个位置匹配第二个组的内容
print( re.search( r"(alex)(eric)com2", "alexericcomeric" ).group() )
代码语言:javascript复制print( "=== {}: 手动设置匹配字符出现的个数 =====" )
print( re.findall( "lxl{1}", "afdafdlxlaaaalxlllll" ) )
print( re.findall( "lxl{1,5}", "afdafdlxlllxasdfqlxlioplxlliiiilxlllllll" ) )
print( re.findall( "lxl{0}", "afdafdlxlllllllsvblxbbblxl" ) )
代码语言:javascript复制print( "=== (): 将其里面的内容作为一个组 =====" )
print( re.findall( "lxl{1}", "afdafdlxlaaaalxlllll" ) )
print( re.findall( "lxl{1,5}", "afdafdlxlllxasdfqlxlioplxlliiiilxlllllll" ) )
print( re.findall( "lxl{0}", "afdafdlxlllllllsvblxbbblxl" ) )
代码语言:javascript复制print( "=== []: 字符集. 选择性匹配[]中的内容 =====" )
print( re.findall( "a[bc]d", "wwwabd" ) )
print( re.findall( "a[bc]d", "wwwacd" ) )
print( re.findall( "a[bc]d", "wwwabcd" ) )
print( re.findall( "a[bc]d", "wwwad" ) )
代码语言:javascript复制# 注意: 当前面说的. ? * 放到字符集[]里面就失去意义了
print( re.findall( "a[.]d", "wwwaqd" ) )
print( re.findall( "a[.]d", "wwwa.d" ) )
# 但是,有几个字符在字符集里还是有特殊意义的
# 1. - :表示从哪到哪, 例如a-z, 从a到z; 1-9, 从1到9
print( re.findall( "a[a-z]m", "reqwasmadfazmfasm" ) )
# 2. ^ : 表示除了***,即取非.
print( re.findall( "a[^1-9]", "fafa2adfa0fadfa8fafda3afa0" ) )
# af ad ad af af
# 3. : 保留其自身的含义.
print( re.findall( "d", "adfa312dfa9adf83dfa-98" ) )
h) 贪婪模式
代码语言:javascript复制print( "=== 贪婪模式: * ?都是贪婪模式, 如果去最小,则加一个? =====" )
# 贪婪模式取最多
print( re.findall( "ad ", "a25423bqa3423dsfa967a" ) )
# ? 则最小匹配
print( re.findall( "ad ?", "a25423bqa3423dsfa967a" ) )
print( re.findall( "ad*?", "a25423bqa3423dsfa967a" ) )
# 如果?后面还有内容, 则不能做到最小匹配
print( re.findall( "ad ?b", "a25423bqa3423dsfa967a" ) )
print( re.findall( "ad*?b", "a25423bqa3423dsfa967a" ) )
i) re 模块常用方法
代码语言:javascript复制'''
re.findall:有() 匹配的是()里的内容
re.search: 找符合条件的第一个,第一个可以在任何位置
re.match:尝试从字符串的起始位置匹配一个模式, 如果不是起始位置匹配成功, match返回none
re.sub: 替换
re.subn: 替换后返回替换次数
re.compile: 编译
re.split: 分割
re.finditer: 类似于findall, 不同之处在于finditer返回的是一个迭代器
'''
代码语言:javascript复制# findall 找到符合条件的全部字符串de集合
print( re.findall( "abc", "a25423bqabc3423dsfa967abc" ) ) # 返回 :['abc', 'abc']
# search 找到符合条件的第一个, 可以在任何位置的第一个. 如果没有匹配,返回None
print( re.search( "abc", "a25423bqa3423abcdsfa967abc" ).group() ) # 返回:abc
print( re.search( "abc", "ab" ) ) # 返回:None
# match 找到符合条件的第一个, 必须在开头位置
print( re.match( "com", "abccomddd" ) ) # 返回None
print( re.match( "com", "comabcddd" ).group() ) # 返回com
代码语言:javascript复制# 注意: 一旦search和match匹配成功以后, 就会返回一个match object对象,
# 而match object对象有以下方法
'''
.start()返回匹配开始的位置
.end() 返回匹配结束的位置
.span() 返回一个元祖包含匹配(开始,结束)的位置
·group()返回被RE匹配的字符串, 可以传递一个或多个参数,返回对应组号匹配的字符串
'''
a = "abc123def"
print( re.match( "([a-z]*)([1-9]*)([a-z]*)", a ).group() ) # 匹配全部内容 结果:abc123def
print( re.match( "([a-z]*)([1-9]*)([a-z]*)", a ).group( 0 ) ) # 默认参数是0, 和没有参数结果一致
print( re.match( "([a-z]*)([1-9]*)([a-z]*)", a ).group( 1 ) ) # 获取第一个组的内容 结果:abc
print( re.match( "([a-z]*)([1-9]*)([a-z]*)", a ).group( 2 ) ) # 获取第二个租的内容 结果:123
print( re.match( "([a-z]*)([1-9]*)([a-z]*)", a ).group( 2, 3 ) ) # 获取第二个,第三个组的内容 结果:('123', 'def')
matchObject = re.match( "([a-z]*)([1-9]*)([a-z]*)", a )
# .start 第二个组的开始位置 返回结果: 3
print( matchObject.start( 2 ) )
# end 第一个组的结束位置 返回结果:3
print( matchObject.end( 1 ) )
# span 第二个组开始位置和结束位置 返回结果是(3, 6)
print( matchObject.span( 2 ) )
代码语言:javascript复制# re.sub: 替换
# re.sub(pattern, repl, str, max=0, flags=0)
# re.sub("查找字符串","替换后的字符串","字符串","替换次数,默认是0,全部替换", 替换模式)
print( re.sub( "g.t", "have", "I get you, I got me, I forgot u", 2 ) ) # 结果: I have you, I have me, I forgot u
# re.subn: 替换, 并返回一个元祖, (替换结果, 替换次数)
# re.subn(pattern, repl, str, max=0, flags=0)
# re.subn("查找字符串","替换后的字符串","字符串","替换次数,默认是0,全部替换", 替换模式)
print( re.subn( "g.t", "have", "I get you, I got me, I forgot u", 2 ) ) # 结果: ('I have you, I have me, I forgot u', 2)
# re.compile: 给定一个正则表达式 pattern,指定使用的模式 flags 默认为0 即不使用任何模式,
# 然后会返回一个 SRE_Pattern (参见 第四小节 re 内置对象用法) 对象
# 当多次调用的时候, 这个方法效率更高
reg = re.compile( ". " )
print( reg.findall( "s" ) )
# re.split: 分割
# split(pattern, string, maxsplit=0, flags=0)
reg = re.compile( r"d " )
print( reg.split( "fafafa2dfad4fadsf153uou", 2 ) ) # 返回结果: ['fafafa', 'dfad', 'fadsf153uou']
# 上面写法和下面等价
print( re.split( r"d ", "fafafa2dfad4fadsf153uou" ) ) # 返回结果: ['fafafa', 'dfad', 'fadsf', 'uou']
print( re.split( "[bc]", "abcd" ) ) # 从前往后, 一个一个分割. 有顺序. 结果: ['a', '', 'd']
# re.finditer 参数和作用与 findall 一样,不同之处在于 findall 返回一个列表, finditer 返回一个迭代器
fi = re.compile("d ")
ite = fi.finditer("fafda2fadfadsf3422adfafa131dfadfa")
for item in ite:
print(item.group(),item.span())
j) 匹配模式
代码语言:javascript复制# 正则表达式匹配模式 -- 可选标志flags, 默认是0
# re.search(pattern, string, flags=0)
# re.findall(pattern, string, flags=0)
# re.match(pattern, string, flags=0)
# re.I: 忽略大小写
print( re.match( "com", "CoM" ) ) # 结果None
print( re.match( "com", "CoM", re.I ).group() ) # 结果: CoM
# re.S: 改变.的匹配行为. 正常.是匹配除了换行符之外的所有字符. 使用re.S模式后, 匹配包括.在内的所有字符
print( re.findall( ".", "a$ dn3a" ) ) # 不包含换行符, 返回结果: ['a', '$', ' ', 'd', '3', 'a']
print( re.findall( ".", "a$ dn3a", re.S ) ) # 包含换行符, 返回结果: ['a', '$', ' ', 'd', 'n', '3', 'a']
k) 原生字符串
代码语言:javascript复制#regstr:原生字符串
print(re.findall("\\","abccom")) # 有特殊含义, python需要转换一次, 正则表达式还要在转换一次, 所有需要四个\\
print(re.findall(r"\","abccom")) #而使用了原生字符r以后, 就避免了多次转换. 只需转换一次, 即正则表达式转换
l ) 优先捕获
代码语言:javascript复制#优先捕获
#在findall里面,如果正则表达式有()也就是组, 则优先取得组的内容.
print(re.findall("www.(baidu|sina).com","www.baidu.com")) # 结果返回: baidu
#在组的前面加一个?: 则去掉优先捕获
print(re.findall("www.(?:baidu|sina).com", "www.baidu.com")) #返回结果:www.baidu.com