regex101: build, test, and debug regex
目录
正则表达式在线验证网站
一、正则表达式
1、. 匹配字符
2、 * 表示重复匹配任意次
3、+ 重复匹配多次 ,不包括0次
4、问号 匹配 0 - 1 次
5、花括号 指定匹配次数
6、贪婪模式和非贪婪模式
7、转义字符 \
8、匹配某种字符类型
9、方括号 表示要匹配 指定的几个字符之一
10、起始、结尾位置 和 单行、多行模式
(1)起始位置 ^
(2)结束位置 $
11、 竖线 表示匹配其中之一
12、() 括号分组
13、一个简单的小例子
二、正则表达式在python中应用
1、findall 返回的是一个list
2、 finditer 返回的是一个迭代器
3、search 返回match对象
4、match 默认从头匹配
5、预加载正则表达式
6、()分组取html标签相关内容
. 可以表示除换行符之外的所有任意单个字符。
如从下文本,选取出所有的颜色
苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的就可以使用 .色进行匹配 如下:
编写 python代码如下 :
import re
content = """
苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的
"""
# r 是防止转义
p = re.compile(r'.色')
for i in p.findall(content):
print(i)
结果如下:
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test1.py
绿色
橙色
黄色
黑色
*
表示匹配前面的子表达式任意次,包括0次。比如,你要从下面的文本中,选择每行逗号后面的字符串内容,包括逗号本身。
苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,就可以这样写正则表达式
,.*
紧跟在 . 后面, 表示 任意字符可以出现任意次, 所以整个表达式的意思就是在逗号后面的 所有字符,包括逗号
验证如下:
还是 2 的例子
花括号表示 前面的字符匹配
指定的次数
。比如 ,下面的文本
红彤彤,绿油油,黑乎乎,绿油油油油
表达式
油{3}
就表示匹配 连续的 油 字 3次表达式
油{3,4}
就表示匹配 连续的 油 字 至少3次,至多 4 次就只能匹配 后面的,如下所示
我们要把下面的字符串中的所有html标签都提取出来,
source = 'Title '
得到这样的一个列表
['', '', '', ' ']
很容易想到使用正则表达式 <.*>
但是它会匹配
在正则表达式中, ‘*’, ‘+’, ‘?’ 都是贪婪地,使用他们时,会尽可能多的匹配内容,
所以, <.*>
中的 星号(表示任意次数的重复),一直匹配到了 字符串最后的 里面的e。
解决这个问题,就需要使用非贪婪模式,也就是在星号后面加上 ?
,变成这样 <.*?>
反斜杠后面接一些字符,表示匹配
某种类型
的一个字符。比如
\d 匹配0-9之间任意一个数字字符,等价于表达式 [0-9]
\D 匹配任意一个不是0-9之间的数字字符,等价于表达式 [^0-9]
\s 匹配任意一个空白字符,包括 空格、tab、换行符等,等价于表达式 [\t\n\r\f\v]
\S 匹配任意一个非空白字符,等价于表达式 [^ \t\n\r\f\v]
\w 匹配任意一个文字字符,包括大小写字母、数字、下划线,等价于表达式 [a-zA-Z0-9_]
缺省情况也包括 Unicode文字字符,如果指定 ASCII 码标记,则只包括ASCII字母
\W 匹配任意一个非文字字符,等价于表达式 [^a-zA-Z0-9_]
比如
[abc]
可以匹配 a, b, 或者 c 里面的任意一个字符。等价于[a-c]
。
[a-c]
中间的 - 表示一个范围从a 到 c。如果你想匹配所有的小写字母,可以使用
[a-z]
一些 元字符 在 方括号内 失去了魔法, 变得和普通字符一样了。
比如
[akm.]
匹配a k m .
里面任意一个字符这里
.
在括号里面不在表示 匹配任意字符了,而就是表示匹配.
这个 字符
如果在方括号中使用
^
, 表示非
方括号里面的字符集合。
^
表示匹配文本的开头
位置。正则表达式可以设定
单行模式
和多行模式
如果是
单行模式
,表示匹配整个文本
的开头位置。如果是
多行模式
,表示匹配文本每行
的开头位置。比如,下面的文本中,每行最前面的数字表示水果的编号,最后的数字表示价格
001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,
$
表示匹配文本的结尾
位置。如果是
单行模式
,表示匹配整个文本
的结尾位置。如果是
多行模式
,表示匹配文本每行
的结尾位置。比如,下面的文本中,每行最前面的数字表示水果的编号,最后的数字表示价格
001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,
为什么要有组的概念呢?因为我们往往需要提取已经匹配的 内容里面的 某些部分的信息。
前面,我们有个例子,从下面的文本中,选择每行逗号前面的字符串,也
包括逗号本身
。
苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的
就可以这样写正则表达式
^.*,
但是,如果我们要求 不要包括逗号 呢?
当然不能直接 这样写
^.*
因为最后的逗号 是 特征 所在, 如果去掉它,就没法找 逗号前面的了。
但是把逗号放在正则表达式中,又会包含逗号。
解决问题的方法就是使用 组选择符 : 括号。
我们这样写
^(.*),
,结果如下
在复杂一点分组如下:
使用 ?P<分组名> 可以给组进行命名,方面后续拿取
代码如下:
import re
content = """苹果,!@苹果是绿色的"""
# r 是防止转义
p = re.compile(r'^(?P(?P(?P.*),)!)@')
for match in p.finditer(content):
print(match.group('a'))
print(match.group('b'))
print(match.group('c'))
输出结果如下:
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test1.py
苹果,!
苹果,
苹果
将文本下工资取出来
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
如下:
[\d.]+万\/每?月
分析:
[\d.]+
表示 匹配 数字或者点的多次出现 这就可以匹配像: 3 33 33.33 这样的 数字
万/每{0,1}月
是后面紧接着的,如果没有这个,就会匹配到别的数字, 比如 Python3 里面的3。其中
每{0,1}月
这部分表示匹配每月
每 这个字可以出现 0次或者1次。还可以用
每?月
因为问号表示 前面的字符匹配0次或者1次
匹配字符串中,所有符合正则的内容
import re
lis = re.findall(r'\d+','我的电话是:10086,张三的电话是10010')
print(lis)
结果
匹配字符串中所有的内容,返回的是一个迭代器,从迭代器中拿到内容需要, .group()
import re
lis = re.finditer(r'\d+', '我的电话是:10086,张三的电话是10010')
for i in lis:
print(i.group())
结果:
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test2.py
10086
10010
search 找到一个结果就返回,返回的是match对象,拿数据需要.group()
import re
lis = re.search(r'\d+', '我的电话是:10086,张三的电话是10010')
print(lis.group())
结果
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test2.py
10086
代码
import re
lis = re.match(r'\d+', '我的电话是:10086,张三的电话是10010')
print(lis.group())
结果
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test2.py
Traceback (most recent call last):
File "D:\pythontest\plane\正则表达式\test2.py", line 4, in
print(lis.group())
AttributeError: 'NoneType' object has no attribute 'group'
代码
import re
lis = re.match(r'\d+', '10086,张三的电话是10010')
print(lis.group())
结果
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test2.py
10086
把参数拿出来提前赋值,如下:
obi = re.compile(r'\d+')
使用时只需 obj.find(内容即可) 其它同理
如下内容:
import re
content = '''张三
李四
王五
赵六'''
# re.S 让.能匹配换行符
obj = re.compile(r"(?P.*?) ", re.S)
result = obj.finditer(content)
for it in result:
print(it.group('c'))
结果如下:
D:\pythontest\plane\venv\Scripts\python.exe D:/pythontest/plane/正则表达式/test2.py
张三
李四
王五
赵六