正则表达式
- 作用
- 函数
- 函数参数
- 查找函数
- re.findall()
- re.search()
- re.match()
- re.finditer()
- re.compile()函数
- 替换函数
- re.sub(pattern,repl,string,count=0,flags=0)
- re.subn()
- 分割函数
- re.split()
- 模式串字符
- 字符类别表达(匹配单个字符)
- \d
- \D
- \s
- \S
- \w
- \W
- [a-z]
- [^a-z]
- .
- 多次匹配字符
- *
- +
- ?
- {2}
- {1,3}
- 组合模式
- [0-9][a-z]
- |
- {}
- 位置
- ^
- $
- \b
- \B
- (?=...)
- (?!...)
- (?<=...)
- (?<!...)
- 分组
- ()
- 其他概念
- 贪婪模式和非贪婪模式
- r的作用
作用
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
函数
函数参数
正则表达式所有的函数一般都包括三个参数:
- 第一个参数:pattern
匹配的正则表达式,类似数据结构的模式串或子串。 - 第二个参数:string
- 要匹配的字符串,类似数据结构的主串。
- 最后一个参数:flags=0
标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。可选标志如下:
字符 | 功能 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
查找函数
re.findall()
功能:在字符串中找到正则表达式所匹配的所有子串,并返回一个列表。
如果没有找到匹配的,则返回空列表。
示例代码:
import re
str='她们分别叫做御坂10086和御坂12306'
x=re.findall('御坂',str)
print(x)
输出:
['御坂', '御坂']
re.search()
功能:查找模式串,只返回查找到的第一个结果。
返回Match对象,包括匹配到的结果以及其在字符串中的位置。
对于Match对象:
- 使用.group()可获取搜索到的值。
- 使用.span()可获取搜索到的值在主串中的位置(下标从0开始)。
- 使用.start()可获取搜索到的值在主串中的开始位置。
- 使用.end()可获取搜索到的值在主串中的结束位置。
示例代码:
import re
str='她们分别叫做御坂10086和御坂12306'
x=re.search('御坂',str)
print(x)
print(x.group())
print(x.span())
print(x.start())
print(x.end())
输出:
<re.Match object; span=(6, 8), match='御坂'>
御坂
(6, 8)
6
8
re.match()
功能:从主串的开头查找模式串,如果主串的开头是模式串,则只返回查找到的结果。否则返回None
返回Match对象,包括匹配到的结果以及其在字符串中的位置。
使用.group()可获取搜索到的值。
和re.search()的区别是re.match()增加了必须在主串开头处匹配的限制。
示例代码:
str='sa加藤惠saber加藤惠sakura加藤惠'
x=re.match('加藤惠',str)
x1=re.match('sa',str)
print(x)
print(x1)
输出:
None
<re.Match object; span=(0, 2), match='sa'>
re.finditer()
功能:查找模式串,返回一个迭代器。
迭代器中的每个元素是Match对象。
示例代码:
str='加藤惠saber加藤惠sakura加藤惠'
iter=re.finditer(r'加藤惠',str)
for x in iter:print(x)
输出:
<re.Match object; span=(0, 3), match='加藤惠'>
<re.Match object; span=(8, 11), match='加藤惠'>
<re.Match object; span=(17, 20), match='加藤惠'>
re.compile()函数
功能:用于编译正则表达式,生成一个正则表达式(Pattern)对象。
re.compile()函数的参数为模式串和标志位。
生成的pattern对象供match()和search()这两个函数使用。
下面以search()举例,用match()也是类似的。
示例代码:
str='她们分别叫做御坂10086和御坂12306'
pattern=re.compile('御坂')
x=pattern.search(str)
print(x)
输出:
<re.Match object; span=(6, 8), match='御坂'>
pattern.search(string,pos,endpos)中的参数:
- 参数1表示主串
- 参数2表示从主串的pos位置开始匹配,默认从主串开始位置开始匹配。
- 参数3表示从主串的endpos位置结束匹配,默认从主串结尾位置结束匹配。
使用re.compile()函数编译后使用pattern.search()函数的结果和直接使用re.search()函数的结果一样。
pattern.search()函数z只是在re.search()函数功能上增加了按照指定主串的位置来匹配参数。
替换函数
re.sub(pattern,repl,string,count=0,flags=0)
参数:
- 参数1:模式串
- 参数2:用来替换的字符串,也可以是个函数。
- 参数3:主串
- 参数4:替换的最大次数,默认为0,代表不限制次数。
- 参数5:标志位,re.I等
示例代码:
str='加藤惠saber加藤惠sakura加藤惠'
x=re.sub('加藤惠','英梨梨',str)
print(x)
输出:
英梨梨saber英梨梨sakura英梨梨
re.subn()
功能:在re.sub()的基础上增加了返回替换次数的功能。
示例代码:
str='加藤惠saber加藤惠sakura加藤惠'
x=re.subn('加藤惠','英梨梨',str)
print(x)
输出:
('英梨梨saber英梨梨sakura英梨梨', 3)
分割函数
re.split()
功能:按照匹配的模式串来分割主串,然后返回列表。
除了模式串和主串,还有参数maxsplit,表示分割次数,默认为0,表示不限制次数。
示例代码:
str='加藤惠saber加藤惠sakura加藤惠asuna'
x=re.split('加藤惠',str)
x1=re.split('加藤惠',str,maxsplit=2)
print(x)
print(x1)
输出:
['', 'saber', 'sakura', 'asuna']
['', 'saber', 'sakura加藤惠asuna']
模式串字符
字符类别表达(匹配单个字符)
表达某一类字符,比如数字,字母等。
\d
用来匹配任意单个数字。
示例代码:
str='j_k加藤惠!!123'
x=re.findall(r'\d',str)
print(x)
输出:
['1', '2', '3']
\D
用来匹配任意单个非数字字符。
示例代码:
str='j_k加藤惠!!123'
x=re.findall(r'\D',str)
print(x)
输出:
['j', '_', 'k', '加', '藤', '惠', '!', '!']
\s
用来匹配任意单个空格。
示例代码:
str='先 有圣人 后 有天'
x=re.findall(r'\s',str)
print(x)
输出:
[' ', ' ', ' ']
\S
用来匹配任意单个非空格字符。
示例代码:
str='先 有圣人 后 有天'
x=re.findall(r'\S',str)
print(x)
输出:
['先', '有', '圣', '人', '后', '有', '天']
\w
用来匹配任意单个汉字、字母、数字或下划线字符。
示例代码:
str='j_k加藤惠!!'
x=re.findall(r'\w',str)
print(x)
输出:
['j', '_', 'k', '加', '藤', '惠']
\W
用来匹配任意单个除了汉字、字母、数字和下划线之外的任意字符
示例代码:
str='j_k加藤惠!!'
x=re.findall(r'\W',str)
print(x)
输出:
['!', '!']
[a-z]
[]表示可以匹配中括号中出现的任意单个字符,并且支持 -。
[a-z]表示可以匹配字母a-z中任意单个字符。
[A-Z],[a-zA-Z0-9]也可以这样类比。
示例代码:
str='j_k加藤惠MM!!123'
x=re.findall(r'[a-z]',str)
print(x)
输出:
['j', 'k']
[^a-z]
取反操作,表示除了字母a-z中任意单个字符
示例代码:
str='j_k加藤惠MM!!123'
x=re.findall(r'[^a-z]',str)
print(x)
输出:
['_', '加', '藤', '惠', 'M', 'M', '!', '!', '1', '2', '3']
.
表示除/n之外的任意单个字符。
示例代码:
str='j_k加藤惠MM!!123\n'
x=re.findall('.',str)
print(x)
输出:
['j', '_', 'k', '加', '藤', '惠', 'M', 'M', '!', '!', '1', '2', '3']
多次匹配字符
匹配多个字符。
*
用来匹配0或多个字符
示例代码:
str='加j藤k惠mm英eee梨riri梨\n'
x=re.findall('[a-z]*',str)
print(x)
输出:
['', 'j', '', 'k', '', 'mm', '', 'eee', '', 'riri', '', '', '']
+
用来匹配1或多个字符
示例代码:
str='加j藤k惠mm英eee梨riri梨\n'
x=re.findall('[a-z]+',str)
print(x)
输出:
['j', 'k', 'mm', 'eee', 'riri']
?
用来匹配0或1个字符,并且启用非贪心模式。
示例代码:
str='加藤惠mm加藤惠'
x=re.findall('(加.惠)?',str)
print(x)
输出:
['加藤惠', '', '', '加藤惠', '']
{2}
用来匹配2个字符
示例代码:
str='加j藤k惠mm英eee梨riri梨\n'
x=re.findall('[a-z]{2}',str)
print(x)
输出:
['mm', 'ee', 'ri', 'ri']
{1,3}
用来匹配1-3个字符
另外{0,3}表示匹配0-3个字符,{1,}表示匹配一个以上字符。
示例代码:
str='加j藤k惠mm英eee梨riri梨\n'
x=re.findall('[a-z]{1,3}',str)
print(x)
输出:
['j', 'k', 'mm', 'eee', 'rir', 'i']
组合模式
将多个模式组合在一起,可以拼接也可以二选一等。
[0-9][a-z]
将模式直接拼接在一起,表示匹配形如单个数字+单个小写字母的两个字符
示例代码:
str='加2j1藤k惠m3m英eee梨ri9ri梨\n'
x=re.findall('[0-9][a-z]',str)
print(x)
输出:
['2j', '3m', '9r']
|
或操作,表示可以匹配任意一种模式
示例代码:
str='加藤惠m3m英梨梨123\n'
x=re.findall('[0-9]|[a-z]',str)
print(x)
输出:
['j', 'k', 'mm', 'eee', 'rir', 'i']
{}
表示在分组后可以以组为单位应用量词。
()表示分组。
如:(abc){3}表示abcabcabc。
示例代码:
str='abcabcabc加藤惠mm英梨梨abcabcabc\n'
x=re.findall('(abc){3}',str)
print(x)
输出:
['abc', 'abc']
位置
限定模式串出现的位置,比如行首,行尾或者在特定符之后等。
^
匹配在字符串开头的模式串。
否则返回空列表。
示例代码:
str='加藤惠mm英梨梨\n'
x=re.findall('^mm',str)
y=re.findall('^加藤惠',str)
print(x)
print(y)
输出:
[]
['加藤惠']
$
匹配在字符串末尾的模式串。
否则返回空列表。
注意:$需放在模式串后面。
示例代码:
str='加藤惠mm英梨梨\n'
x=re.findall('mm$',str)
y=re.findall('英梨梨$',str)
print(x)
print(y)
输出:
[]
['英梨梨']
\b
匹配在边界的模式串。
\b所表示的边界,是字母、数字、汉字与特殊字符的边界,放在模式串右边则表示字符右边界。此时字母、数字、汉字均可视为同一类字符。
示例代码:
str='123.megumi我我我'
x=re.findall(r'\bme',str) #必须加r或者使用\\b
x1=re.findall(r'mi\b',str)
print(x)
print(x1)
输出:
['me']
[]
\B
匹配在非单词边界的模式串。
与\b完全相反,只要字母、数字、汉字之间没有特殊字符都可以匹配。
示例代码:
str='123.megumi我我我'
x=re.findall(r'\Bme',str)
x1=re.findall(r'mi\B',str)
print(x)
print(x1)
输出:
[]
['mi']
(?=…)
匹配出现在…之前的模式串。
(?=…)需放在模式串右边。
另外这里的之前非常严格,必须是紧挨着…模式串才能匹配到。
示例代码:
str='saber加藤惠sabersakura'
x=re.findall(r'saber(?=sakura)',str) #匹配sakura之前的saber
print(x)
输出:
['saber']
(?!..)
匹配不出现在…之前的模式串。
(?!..)需放在模式串右边。
这里的之前也非常严格,必须是紧挨着…模式串才能匹配到。
示例代码:
str='saber,saber加藤惠sabersakura'
x=re.findall(r'saber(?!sakura)',str) #匹配除了sakura前面以外的saber
print(x)
输出:
['saber', 'saber']
(?<=…)
匹配出现在…之后的模式串。
(?<=…)需放在模式串左边。
这里的之后非常严格,必须是紧挨着…模式串才能匹配到。
示例代码:
str='加藤惠saber加藤惠sakura加藤惠'
x=re.findall(r'(?<=sakura)加藤惠',str) #只匹配sakura之后的加藤惠
print(x)
输出:
['加藤惠']
(?<!..)
匹配不出现在…之后的模式串。
(?<=…)需放在模式串左边。
这里的之后非常严格,必须是紧挨着…模式串才能匹配到。
示例代码:
str='加藤惠saber加藤惠sakura加藤惠'
x=re.findall(r'(?<!sakura)加藤惠',str)
print(x)
输出:
['加藤惠', '加藤惠']
分组
()
用来将字符打包成一个组处理
只会匹配出()的内容,()外的内容都是作为条件而已。
对于search(),findall()这种只匹配一个对象的函数,返回的Match对象只能返回一个最外面一层的分组。
对于Match对象,可以使用.groups()查看匹配到的每个分组。
示例代码:
str='加藤惠saber加藤惠sakura加藤惠'
x=re.search(r'((加藤惠)s)',str)
y=re.findall(r'((加藤惠)s)',str)
print(x) #只返回最外层的一个分组
print(x.group())
print(x.groups()) #查看所有分组
print(y)
输出:
<re.Match object; span=(0, 4), match='加藤惠s'>
加藤惠s
('加藤惠s', '加藤惠')
[('加藤惠s', '加藤惠'), ('加藤惠s', '加藤惠')]
其他概念
贪婪模式和非贪婪模式
贪婪匹配:最大长度匹配。
非贪婪匹配:最少长度匹配。
举例:
string='abcabc' #主串(要被匹配的字符串)
pattern='ab.*c' #模式串(匹配的正则表达式)
贪婪匹配结果为abcabc。
非贪婪匹配结果为abc。
默认为贪婪模式。在量词后面加个问号?就是非贪婪模式。这个问号称为非贪婪限定符。
量词如:{m,n},*,+,?
r的作用
如:r"123",避免转义字符\在字符串中起作用。
参考:菜鸟驿站