正则表达式
需要导入模块re
通配符:.
:句点与除换行符外的其他字符都匹配。
匹配单个字符
字符 | 功能 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意1个字符(除了\n) |
[ ] | 匹配[ ]中列举的字符 |
\d | 匹配数字 |
\D | 匹配非数字 |
\s | 匹配空白,如 空格 tab |
\S | 匹配非空白 |
\w | 匹配单词字符,a-z A-Z 0-9 _ |
\W | 匹配非单词字符 |
[^ ] | 匹配不再[ ]中的字符 |
a|b | 匹配a或b |
匹配多个字符
字符 | 功能 |
---|---|
* | 匹配前一个字符出现0次或无限次 |
+ | 出现1次或无限次,至少一次 |
? | 可有可无 |
{m} | 出现m次 |
{m,n} | 出现m到n次 |
其他一些匹配
字 符 | 功能 |
---|---|
(re) | 匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (…), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#…) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配字母数字 |
\W | 匹配非字母数字 |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]. |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]. |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
\1…\9 | 匹配第n个分组的子表达式。 |
\10 | 匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。 |
————————————————
原文链接:https://blog.csdn.net/weixin_40907382/article/details/79654372
匹配的方式
re.match
:从开始位置开始匹配,如果开头没有则无;
re.search
:搜索整个字符串;
re.findall
:搜索整个字符串,返回一个list;
# match 从开头匹配,开头匹配不成功则直接报错
>>> re.match(r'ab', 'abuyab1234ab9').group()
'ab'
>>> re.match(r'ab', 'eeabuyab1234ab9').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
# search 寻找整个字符串,有则返回
>>> re.search(r'ab', 'eeabuyab1234ab9').group()
'ab'
# 匹配字符串返回一个list
>>> re.findall(r'ab', 'eeabuyab1234ab9')
['ab', 'ab', 'ab']
# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
匹配时的标志修饰符
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
>>> import re
>>> re.search(r'[a-z]+', 'liuyaN1234ab9').group()
'liuya'
>>> re.search(r'[a-z]+', 'liuyaN1234ab9', re.I).group() # re.I 对大小写不敏感
'liuyaN'
一些匹配符的解释
\b
匹配单词边界
它匹配一个单词的边界,比如空格等,不过它是一个‘ 0 ’长度字符,它匹配完的字符串不会包括那个分界的字符。而如果用 ’\s’ 来匹配的话,则匹配出的字符串中会包含那个分界符。
例:
>>> s ='abc abcde bc bcd'
>>> re.findall(r'\bbc\b',s) # 匹配一个单独的单词 'bc' ,而当它是其它单词的一部分的时候不匹配
['bc'] # 只找到了那个单独的 'bc'
>>> re.findall(r'\sbc\s',s) # 匹配一个单独的单词 'bc'
[' bc '] # 只找到那个单独的 'bc',不过注意前后有两个空格,可能有点看不清楚
‘\B’ 匹配非边界
和 ’\b’ 相反,它只匹配非边界的字符。它同样是个 0 长度字符。
接上例:
>>> re.findall( r'\Bbc\w+',s) # 匹配包含’bc’但不以’bc’为开头的单词
['bcde'] # 成功匹配了 ’abcde’ 中的 ’bcde’ ,而没有匹配 ’bcd’
(?:)
无捕获组
当你要将一部分规则作为一个整体对它进行某些操作,比如指定其重复次数时,你需要将这部分规则用 ’(?:’ ‘)’ 把它包围起来,而不能仅仅只用一对括号,那样将得到绝对出人意料的结果。
例:匹配字符串中重复的 ’ab’
>>> s='babab abbabb aabaab'
>>> re.findall(r'\b(?:ab)+\b',s)
['ababab']
# 如果仅使用一对括号,看看会是什么结果:
>>> re.findall(r'\b(ab)+\b',s)
['ab']
# 这是因为如果只使用一对括号,那么这就成为了一个组 (group) 。
(?# )’
注释
Python 允许你在正则表达式中写入注释,在 (?#’ ‘)
之间的内容将被忽略。
组
(‘’)
无命名组
最基本的组是由一对圆括号括起来的正则式。比如上面匹配包夹在字母中间的数字的例子中使用的 (\d+)
:
>>> s = 'aaa111aaa , bbb222 ,333ccc'
>>> re.findall(r'[a-z]+(\d+)[a-z]+',s)
['111']
可以看到 findall 函数只返回了包含在 ’()’ 中的内容,而虽然前面和后面的内容都匹配成功了,却并不包含在结果中。
除了最基本的形式外,我们还可以给组起个名字,它的形式是
(?P<name>…)
命名组
(?P
代表这是一个 Python 的语法扩展 ’<…>’ 里面是你给这个组起的名字,比如你可以给一个全部由数字组成的组叫做 ’num’ ,它的形式就是 (?P<num>/d+)
。起了名字之后,我们就可以在后面的正则式中通过名字调用这个组,它的形式是
(?P=name)
调用已匹配的命名组
要注意,再次调用的这个组是已被匹配的组,也就是说它里面的内容是和前面命名组里的内容是一样的。
我们可以看更多的例子:请注意下面这个字符串各子串的特点。
>>> s='aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg'
>>> re.findall(r'([a-z]+)\d+([a-z]+)', s) # 找出中间夹有数字的字母
[('aaa', 'aaa'), ('fff', 'ggg')]
>>> re.findall(r'(?P<g1>[a-z]+)\d+(?P=g1)',s) # 找出被中间夹有数字的前后同样的字母
['aaa']
>>> re.findall(r'[a-z]+(\d+)([a-z]+)',s) # 找出前面有字母引导,中间是数字,后面是字母的字符串中的中间的数字和后面的字母
[('111', 'aaa'), ('777', 'ggg')]
我们可以通过命名组的名字在后面调用已匹配的命名组,不过名字也不是必需的。
‘\number’ 通过序号调用已匹配的组
正则式中的每个组都有一个序号,序号是按组从左到右,从 1 开始的数字,你可以通过下面的形式来调用已匹配的组
比如上面找出被中间夹有数字的前后同样的字母的例子,也可以写成:
>>> re.findall(r'([a-z]+)\d+\1',s)
'aaa']
我们再看一个例子
>>> s='111aaa222aaa111 , 333bbb444bb33'
>>> re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)',s) # 找出完全对称的 数字-字母-数字-字母-数字 中的数字和字母
[('111', 'aaa', '222', 'aaa', '111')]
摘自原文链接:https://blog.csdn.net/weixin_40907382/article/details/79654372