1. 什么是正则?有什么用?
可以利用正则表达式简单、快速和高效的检索出我们需要查找的文字
正则表达式非常的强大,使用正则表达式关键的地方在于如何写出正确的【表达式语法】
- 在线验证正则表达式网站 点我访问
2. 正则表达式中的特殊符号
2.1 *(星号)-重复匹配任意次
*
表示匹配前面的字符任意次,包括0次
比如:你要从下面的文本中,选择逗号后面字符串内容,包括逗号本身,注意,这里的逗号是中文的逗号。
苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,
就可以这样写正则表达式:,.*
*
紧跟在 .
后面,表示 任意字符可以出现任意次,所以整个表达式的意思就是在逗号后面的所有字符,包括逗号
2.2 +(加号)-重复匹配多次
+
表示匹配前面的子表达式一次或多次,不包括0次
比如:还是2.1 中的例子,你要从文本中,选择每行逗号后面的字符串内容,包括逗号本身。
但是添加一个条件,如果逗号后面没有内容,就不要选择。
就可以这样写正则表达式:,.+
2.3 {}(花括号)-匹配指定的次数
{}
表示前面的字符匹配指定的次数
比如,下面的文本
红彤彤,绿油油,黑乎乎,绿油油油油
表达式:油{3,4}
就表示匹配连续的 油 字 至少3次,至多4次
2.4 [](方括号)-匹配几个字符之一
[]
表示要匹配某几种类型的字符
比如:[abc]
可以匹配 a,b或者c里面的任意一个字符。等价于[a-c]
[a-c]
中间的- 表示一个范围从 a 到 c。
如果你想匹配所有的小写字符,可以使用[a-z]
- 注意:一些元字符在方括号内失去了魔法,变得和普通字符一样了
比如:[akm.]
匹配a,k,m,.里面的任意一个字符
这里的.
在括号里面不在表示匹配任意字符了,而就是表示匹配 . 这个字符
- 如果在放括号中使用
^
表示非的意思
比如[^\d]
表示选择非数字的字符
2.5 ()(括号)-组选择
括号称为正则表达式的 组选择,是从正则表达式匹配的内容里面扣去除其中的某些部分
例如:从下面的文本中,选择每行逗号前面的字符串,也包括逗号本身。
苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的
我们就可以这样写正则表达式^.*,
但是,我们要求不要包括逗号呢?
当然不能直接写^.*
因为最后的逗号是特征所在,如果去掉它,就没法找逗号前面的字符了
但是把逗号放在正则表达式中,又会包含逗号
解决问题的方法就是使用组选择符:括号。
我们这样写 ^(.*),
这样就可以实现我们的需求
2.6 ?(问号)-匹配0-1次
?
表示匹配前面的子表达式0次或者1次
3. 贪婪模式和非贪婪模式
在正则表达式中,
* + ?
都是贪婪的,使用它们时,会尽可能多的匹配内容
我们要把下面的字符串中所有的html标签都提取出来
source = "<html><head><title>Title</title>"
我们想要得到这样的一个列表
['<html>','<head>','<title>','</title>']
很容易的想到使用正则表达式:<.*>
- 在python中完整的写法:
source = "<html><head><title>Title</title>"
import re
p = re.compile(r'<.*>')
print(p.findall(source))
但是运行结果是
["<html><head><title>Title</title>"]
- 尽可能多的匹配内容,这就是贪婪模式
如果我们需要使用非贪婪模式,即:尽可能少的匹配我们的内容
我们需要在星号后面加上?,变成.*?
就可以实现我们想要的结果
4. 对元字符的转义
反斜杠\
在正则表达式中有多种用途。
比如,我们要在下面的文本中搜索所有点前面的字符串,也包含点本身
苹果.是绿色的
橙子.是橙色的
香蕉.是黄色的
我们马上会想到可以这样写正则表达式.*.
聪明的你会认识到这样写是不对的,
因为为什么第一个 . 就是匹配任意字符,第二个. 就是以. 结尾呢
这是我们就可以使用反斜杠\
进行转义。
正确的正则表达式为:.*\.
匹配某种字符类型
反斜杠\
后面接一些字符,表示匹配某种种类类型的一个字符。
\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]
\W
匹配任意一个非文字字符,等价于表达式[^a-zA-Z0-9]
反斜杠\
也可以用在方括号里面,比如[\s,.]
表示匹配:任何空白字符,或者逗号,或者点
5. 起始位置、结束位置和单行、多行模式
^
表示匹配文本的起始位置
正则表达式可以设定【单行模式】和【多行模式】
如果是【单行模式】,表示匹配整个文本的开头位置
如果是【多行模式】,表示匹配文本每行的开头位置
$
表示匹配文本的结束位置
如果是【单行模式】,表示匹配整个文本的结束位置
如果是【多行模式】,表示匹配文本每行的结束位置
比如:下面的文本中,每行最前面的数字表示水果的编号,最后的数字表示价格
001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80
如果我们要获取所有的水果编号,用这样的正则表达式 [^\d+]
如果我们要获取所有的水果价格,用这样的正则表达式[\d+$]
- 在python中的写法
content = ```001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80
```
import re
# re.M 表示开启多行模式 compile函数的第二个参数表示匹配的模式
p = re.compile(r'^\d+',re.M)
for one in p.findall(content):
print(one)
6. 使用正则表达式切割字符串
字符串对象的split()方法只是用与非常简单的字符串分割情形,当你需要更加灵活的切割字符串的时候,就不好用了。
比如:我们需要从下面的字符串中提取武将的名字。
我们发现这些名字之间,有的是分号隔开,有的是逗号隔开,有的是空格隔开,而且分割符号周围还有不定数量的空格
names = '关羽; 张飞, 赵云,马超, 黄忠 李逵'
这时,最好使用功能正则表达式里面的split方法:
import re
names = '关羽; 张飞, 赵云,马超, 黄忠, 李逵'
namelist = re.split(r'[;,\s]*',names)
print(namelist)
正则表达式[;,\s]\s*
指定了,分割符为分号、逗号、空格里面的任意一种均可,并且该符号周围可以有不定数量的空格