正则表达式,又称规则表达式(Regular Expression),是使用单个字符串来描述、匹配某个句法规则的字符串,常被用来检索、替换那些符合某个模式(规则)的文本。
简单来说,正则表达式就是使用:字符串定义规则,并通过规则去验证字符串是否匹配。
正则的三个基础方法
Python正则表达式,使用re模块,并基于re模块中三个基础方法来做正则匹配。 分别是:match()、search()、findall() 三个基础方法
match()函数
设置注册用户名
从被匹配字符串开头进行匹配, 匹配成功返回匹配对象(包含匹配的信息),匹配不成功返回空。
match()函数的使用形式如下:
python
复制代码
match(匹配规则, 被匹配字符串)
示例代码:
python
复制代码
import re
message ='张三、李四、王五、赵六'
result = re.match('张三',message)
print(result)
代码执行结果:
python
复制代码
<re.Match object; span=(0,2), match='张三'>
返回的结果以正则的类型输出,其中span=(0,2)指明匹配的位置,表示在字符串索引号为0~2的位置匹配成功,匹配的内容为"张三'。
现将以上代码进行修改,修改后的代码如下:
python
复制代码
import re
message ='张三、李四、王五、赵六
result=re.match('三',message)
print(result)
代码执行结果:
python
复制代码
None
虽然字符三'在message中,但并不位于message的开头,所以匹配不成功
search()函数
search(匹配规则, 被匹配字符串) 搜索整个字符串,找出匹配的。从前向后,找到第一个后,就停止,不会继续向后
search()函数的使用形式如下:
python
复制代码
search(匹配规则, 被匹配字符串)
功能:表示从参数2(字符串类型数据)中查找满足参数1(正则表达式)的内容,如果匹配了多个参数1,只返回第1个匹配成功的信息。
示例代码:
python
复制代码
import re
message ='张三、李四、王五、赵六、王五
result=re.search('王五',message)
print(result)
代码执行结果:
python
复制代码
<re.Match object; span=(6, 8), match='王五'>
由于message中存在两个'王五,因此执行代码后会输出第1个'王五'所在的位置及内容。
findall()函数
findall(匹配规则, 被匹配字符串) 匹配整个字符串,找出全部匹配项
findall()函数的使用形式如下:
python
复制代码
findall(匹配规则, 被匹配字符串)
表示从参数2(字符串类型数据)中查找满足参数1(正则表达式)的内容,如果匹配了多个参数1,则返回匹配成功的全部信息。
示例代码:
python
复制代码
import re
message ='张三、李四、王五、赵六、王五'
result = re.findall('王五',message)
print(result)
代码执行结果:
python
复制代码
['王五',王五']
findall()并不返回匹配的位置,只返回匹配的全部内容 。
元字符匹配
上面只是基础的字符串匹配,正则最强大的功能在于元字符匹配规则。
xyz\]:字符集合,即匹配所包含的任意一个字符。例如\[abc\]可以匹配plain中的a。
\[a-z\]:字符范围,即匹配指定范围内的任意字符。例如\[a-z\]可以匹配a到z范围内的任意小写字母。示例代码:
```python
import re
message = 'Python93,C87,Java63,C++88'
result_1 = re.search('[cn]',message)
result_2 = re.findall('[0-9]',message)
result_3 = re.findall('[cn][0-9]',message)
print(result_1,result_2,result_3)
```
代码执行结果:
```python
['g', '3', '8', '7', '6', '3', 'g', '8'] 「'n9']
```
第3行代码表示从message中匹配字符c或n,只要message中包含c或n,执行代码后就会输出匹配到的第1个字符。需要注意的是大写的C是不能匹配的。
第4行代码表示从message中匹配0\~9的任何一个数字,即匹配全部数字,由于使用了findall()函数,因此程序会将message中的全部数字输出。
第5行代码中的正则表达式包含\[cn\]\[0-9\],表示需要匹配两个字符,且第1个字符是c或n、第2个字符是数字。
数量匹配:

边界匹配:

实例代码:
```python
import re
message = 'da2a7ddbre77yifed777t3fefd7777b'
result = re.findall('[a-z]*[0-9][a-z]',message)#前面的字母可以出现零到无数次"*"
print(result)
```
代码执行结果:
```python
['da2a', "7d',7y',"7t','3f','7b']
```
\*和+的区别
\*:匹配前面的子表达式任意次(大于等于0次)。
+:匹配前面的子表达式一次或多次。
### 示例代码(验证手机号码的正确性):
```python
import re
phone_num = input("请输入您的手机号码:")#13155558888
result = re.findall('^1[0-9]{10}$',phone_num)
print(result)
```
当用户输入的内容超过11位或不足11位时,则不满足手机码的要求,与正则表达式不匹配,程序将返回几。例如输入错误的手机号码1377772,验证结果如下:
```python
请输入您的手机号码:1377772
[]
```
当用户输入的手机号码与正则表达式相匹配时,代码程序将输出匹配的内容。例如输入正确的手机号码15155555555,验证结果如下:
```python
请输入您的手机号码:15155555555
[15155555555]
```
### 示例代码(验证QQ号码是否合规):
```python
import re
QQ_number = input("请输入您的QQ号:")
result = re.match('[1-9][0-9]{4,10}$',QQ_number)
print(result)
```
QQ号码的位数为5\~11位,且第1个数字不能为0。第3行代码使用了match(),需要从输入的首字符开始匹配,因此匹配的正则表达式可以省略\^,\[1-9\]表示匹配的第1个数字只能为1\~9,不能为0。\[0-9\]{4,10}表示可以匹配4\~10个数字,$表示必须要匹配到最后一个字符。
### 示例代码(验证网站用户名的正确性):
```python
import re
use_name = input("请输入您的用户名:")
result = re.findall('^[A-Za-z_][A-Za-z0-9_]{7,}$',use_name)
print(result)
```
第一个字符必须是**字母(大小写均可)或下划线** 后续字符可以是**字母、数字或下划线** ,且**至少出现 7 次**(加上第一个字符,总长度至少为 8)。
单字符匹配:
\\d:匹配一个数字类字符,等价于\[0-9\]。
\\D:匹配一个非数字类字符,等价于\[\^0-9\],\^在中括号中属于非,即不匹配输入字符的首位字符。
\\s:匹配任何不可见字符,包括空格、制表符、换页符等,等价于\[\\f \\n\\r\\t\\v\]。
\\S:匹配任何可见字符,等价于\[\^\\f \\n\\r\\t\\v\]。
**\\w:** 匹配包括下画线的任何单词字符,等价于"\[A-Za-z0-9_\]"。
**\\W:** 匹配任何非单词字符,等价于"\[\^A-Za-z0-9_\]"。
\\f:匹配一个分页符。
\\n:匹配一个换行符。
\\r:匹配一个Enter键符。
\\t:匹配一个制表符。
\\v:匹配一个垂直制表符。
**.:**匹配除"\\n"和"\\r"之外的任何单个字符。
示例代码(验证用户名的正确性):
```python
import re
use_name = input("请输入您的用户名:")
result = re.findall('^[A-Za-z_]\w{7,}$',use_name)
print(result)
```
代码执行结果1(输入正确的用户名):
```python
请输入您的用户名:chaoxiang1234
['chaoxiangl234']
```
代码执行结果2(输入错误的用户名):
```python
请输入您的用户名:chaoxiang1234#
[]
```
示例代码(匹配非单词边界):
```python
import re
message = 'verb very never every'
result = re.findall(r'\w+er\B',message) #\b是转义字符
print(result)
```
代码执行结果:
```python
['ver','ver', 'ever']
```
由于verb中的er并不是单词的边界,且er的前面有一个单词v,因此此字符串将会被匹配上。very中的ver也能被匹配上。由于never中的er是单词的边界,因此不会被匹配上。every中的er不是单词的边界,且er的前面有单词ev,因此匹配的内容是ever。
```python
import re
message = 'verb very never every'
result = re.findall('.e',message)
print(result)
```
代码执行结果:
```python
['ve', 've', 'ne', 've', 'e', 've']
```
其中第1个've'从'verb'中匹配获取;第2个've'从'very'中匹配获取;第3个'ne'从'never'中匹配获取;第个've'从'never'中获取;第5个'e'从'every'中的e和前面的空格匹配获取,由于'.可以匹配除"\\n"和"\\r"之外的住何单个字符,因此'.e'可以匹配空格和'e';第6个've'从'every'中匹配获取。
### 贪婪和非贪婪模式
贪婪和非贪婪模式指是否匹配更多内容,具体使用如下。贪婪模式:默认匹配模式都是贪婪模式,匹配形式是尝试匹配尽可能多的字符,只要满足正则表达式要求会匹配最多的字符。
示例代码(默认匹配模式为贪婪模式):
```python
import re
message = 'ccc739134792hd'
result = re.findall('ccc\d+',message)
print(result)
```
代码执行结果:
```python
['ccc739134792']
```
由于默认匹配模式是贪婪模式,因此会尽可能多地匹配数字。当从'ccc739134792hd'中匹配到了'ccc7'之后还会继续匹配尽可能多的数字。
非贪婪模式:匹配形式是尝试匹配尽可能少的字符,一旦满足正则表达式要求就不再继续匹配。在次数限制操作符后面加上"?"可以将匹配模式转换为非贪婪模式。
示例代码(将匹配模式转换为非贪婪模式):
```python
import re
message = 'ccc739134792hd'
result = re.findall('ccc\d+?',message)
print(result)
```
代码执行结果:
```python
['cce7']
```
正则表达式部分最后增加了一个"?",表示使用非贪婪模式匹配,只要匹配到'ccc'且后面有一个数字就不会再继续往后匹配。
### 或和组
如果需要筛选出组合条件下的字符数据,可以使用或。如果需要筛选后的某部分内容,可以使用组。或:用"!"表示,表示将两个匹配条件进行逻辑"或"(or)运算。
示例代码(匹配表达式中两个匹配条件中的一个匹配条件):
```python
import re
message = 'verb very never every'
result = re.findall('\w+ev|\w+ry',message)
print(result)
```
代码执行结果:
```python
['very', 'nev','every']
```
\\w+eV表示匹配个或多个单词字符,且后面的字符为ev。"w+ry'表示匹配一个或多个单词字符,且后面的字符为ry。
组:用"(表达式)"表示,表示将(中的表达式定义为组,并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个组)。示例代码(使用组的形式获取组中的内容):
```python
import re
message = 'verb very never every'
result = re.findall("e(.+)(.)r",message)
print(result)
```
代码执行结果:
```python
[('rb very never ev','e')]
```
该模式会尽可能多地匹配内容。第2个组匹配除"n"和""之外的任何单个字符(包含空格)。即从字符串的**第1个字符e开始,可以一直匹配到最后一个字符r**,因此匹配的内容是'erb very never ever。但输出时只会输出组中的内容,并不会将所有匹配的内容输出,由于有两个组,因此会输出这两个组中的内容。
### sub()和 compile()方法
sub()和compile()方法分别用于将字符进行替换和将字符串转换为正则表达式。sub()方法的使用形式如下,即将字符串参数3中所有与参数1匹配的字符替换为参数2。
```python
sub(参数1,参数2,参数3)
```
示例代码:
```python
import re
content ='dh932hf9f934hfnf39d'
content = re.sub('\d','0',content)
print(content)
```
代码执行结果:
```python
dh000hfof000nfnf00d
```
将字符串content中满足正则表达式\\d(0-9数字)的内容全部替换为0。
compile()方法用于创建一个正则表达式对象,可以直接使用正则表达式对象的方法匹配其他内容。示例代码:
```python
import re
contentl ='2020 12 15 12:00'
pattern = re.compile('\d{2}:\d{2}')
print(pattern.findall(contentl))
```
代码执行结果:
```python
['12:00']
```
直接使用pattern,万法的形式,匹配content1中满足pattern正则表达式对象的信息。