一、正则表达式简单介绍
1、什么是正则表达式
正则表达式就是对字符串的一种操作,具体操作有:查找、替换、分割、对比、插入、添加等。
其中最常用的三种操作:查询、替换、分割
2、正则(re)的用法
正则是一个特殊的字符表达式,它能够帮助你方便的检查字符串是否和某一格式匹配。
由于Python中本身就有转义字符,所以为了更好的区分,在使用正则表达式的时候,加上前缀“r”
这样就不用考虑转义问题啦
s = r"asd\das"
二、正则的基本用法
学习正则,就是学习正则的函数和正则符号的用法,怎样构造正则表达式。
我们在这第二部分先不学习正则符号,咱们先简单看一下正则里面有哪些常用函数。
首先,我们学习正则模块,就要先导入模块。
import re
for e in dir(re): # dir(re)
if e.islower() and not e.startswith('_'): # 去除大写和以_开头的
print(e, end=' ')
# 结果 : compile copyreg enum error escape findall finditer
# fullmatch functools match purge search split sub subn template
我们可以通过re的自省可以可以看到上述正则(re)可以调用的函数函数。下面我们就介绍一下常用函数。
1、re模块常用函数
- re.match()
re.match 从字符串的开始位置匹配。匹配成功返回一个Match对象,匹配失败的话,返回Nnone。
函数语法格式:match(pattern, string, flags=0)
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用来控制正则匹配的方式 |
results = re.match('www', 'www.asd.www')
print(results) # 匹配成功
# 结果:<re.Match object; span=(0, 3), match='www'>
results = re.match('com', 'www.asd.www')
print(results) # 没有匹配成功
# 结果 None
从上述代码,我们可以看到匹配成功之后返回的是一个Match对象,Match对象不是我们先要的内容,但是我们从结果:
<re.Match object; span=(0, 3), match='www'>
可以看到,span=(0, 3) 匹配位置索引,和match='www',匹配内容。
那我们自省一下返回的结果,让我们看看这个Match对象有没有可以使用的方法。
results = re.match('www', 'www.asd.www')
print(results) # 匹配成功
# 结果:<re.Match object; span=(0, 3), match='www'>
for e in dir(results):
if e.islower() and not e.startswith('_'): # 去除大写和以_开头的
print(e, end=' ')
# 自省结果:end endpos expand group groupdict groups
# lastgroup lastindex pos re regs span start
# string None
我们可以看到,Match对象有许多方法。在此我介绍一下最常用的就是:start,end,group。
这三个是什么意思呢?
- start:返回匹配开始位置
- end:返回匹配结束位置
- group:返回匹配内容
接下来让我们代码演示一下。
results = re.match('www', 'www.asd.www')
print(results) # 匹配成功
# 结果:<re.Match object; span=(0, 3), match='www'>
print(f'匹配开始位置:{results.start()} '
f'匹配结束位置:{results.end()} '
f'匹配内容:{results.group()} ')
# 结果:匹配开始位置:0 匹配结束位置:3 匹配内容:www
- re.search()
re.search 检查整个字符串,返回第一个成功匹配的信息,否则返回None。
函数语法格式:re.search(pattern, string, flags=0)
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用来控制正则匹配的方式 |
results = re.search('asd', 'asd.asd.asd')
print(results) # 匹配成功
# 结果:<re.Match object; span=(0, 3), match='asd'>
print(f'匹配开始位置:{results.start()} '
f'匹配结束位置:{results.end()} '
f'匹配内容:{results.group()} ')
# 结果:匹配开始位置:0 匹配结束位置:3 匹配内容:asd
results = re.search('asd', 'qweasd.asd')
print(results) # 匹配成功
# 结果:<re.Match object; span=(3, 6), match='asd'>
print(f'匹配开始位置:{results.start()} '
f'匹配结束位置:{results.end()} '
f'匹配内容:{results.group()} ')
# 结果:匹配开始位置:3 匹配结束位置:6 匹配内容:asd
- re.findall()
re.findall 检查字符串,找到所有匹配内容,而后返回一个字符串,否则返回一个空列表。
函数语法表达式:re.findall(pattern, string, flags=0)
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用来控制正则匹配的方式 |
results = re.findall('asd', 'qweasd.asd')
print(results) # 匹配成功
# 结果:['asd', 'asd']
results = re.findall('zxc', 'qweasd.asd')
print(results)
# 结果:[]
- re.finditer()
re.finditer 在字符串中找到所有匹配内容,并返回一个迭代器,没有就返回None。
函数语法格式:re.finditer(pattern, string, flags=0)
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用来控制正则匹配的方式 |
results = re.finditer('asd', 'qweasd.asd')
print(results) # 匹配成功
for e in results:
print(type(e), e.group())
# 结果:<class 're.Match'> asd
# <class 're.Match'> asd
results = re.finditer('zxc', 'qweasd.asd')
print(results)
for e in results:
print(type(e), e.group())
# 结果:None
上述代码可以清楚的看到,迭代器中存放的是Match对象,我们要想获取匹配内容就要通过Match对象的group方法。
- re.split()
re.split 按照能够匹配的内容,把字符串分割。
函数语法格式:re.split(pattern, string, maxsplit=0, flags=0)
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
maxsplit | 分割次数,默认是0,不限制次数,例如maxsplit=1,分割一次 |
flags | 标志位,用来控制正则匹配的方式 |
results = re.split('z', 'qwezasdzasdz')
print(results)
# 结果:['qwe', 'asd', 'asd', '']
results = re.split('z', 'qwezasdzasdz', maxsplit=1)
print(results)
# 结果:['qwe', 'asdzasdz']
- re.sub()
re.sub 替换字符串中匹配的内容。
函数语句格式:re.sub(pattern, repl, string, count=0, flags=0)
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
rel | 要替换的内容 |
count | 替换次数,默认是0,不限制次数,例如count=1,替换一次 |
flags | 标志位,用来控制正则匹配的方式 |
results = re.sub('z', '2', 'qwezasdzasdz')
print(results)
# 结果:qwe2asd2asd2
results = re.sub('z', '2', 'qwezasdzasdz',count=1)
print(results)
# 结果:qwe2asdzasdz
这些就是我们介绍的一些常用函数。接下来让我们看看正则的符号吧
2、re模块常见的符号
- 常用的特殊字符
让我们先看看这些字符的定义。
符号 | 描述 |
. | 匹配所有字符,换行符(\n)除外 |
^ | 匹配字符串的开头 |
$ | 匹配字符串的结尾 |
* | 贪婪匹配,匹配0次或多次 |
+ | 贪婪匹配,匹配1次或多次 |
? | 匹配 0 或 1(贪婪) |
*?、+?、?? | 上述三个的非贪婪形式 |
{m.n} | 匹配 m 到 n 次 |
{m.n}? | 上述的非贪婪版 |
[] | 匹配一组字符 |
| | 类似逻辑运算的或 |
() | 匹配括号内的 正则表达式,在字符串中检索或匹配内容 |
看到上述这些字符是不是很头痛,还有更好玩的呢?
它们单独使用没有什么意义,一般都是组合使用是不是很惊喜。
接下来让我们用代码来解释一下上述符号内容。
# 两个特殊的符号’^‘和’$'。他们的作用是分别指出一个字符串的开始和结束
# "^asd":表示所有以"asd"开始的字符串("asdre","asd cat"等)
# "of despair$":表示所以以"asd"结尾的字符串
# "^abc$":表示开始和结尾都是"abc"的字符串
# 也可以在方括号里用'^'表示不希望出现的字符,'^'应在方括号里的第一位。
# 如:"%[^a-zA-Z]%"表示两个百分号中不应该出现字母。
# '','+'和'?'这三个符号,表示一个或一序列字符重复出现的次数。
# 它们分别表示“没有或更多”,“一次或更多”还有“没有或一次”。
# "abc+":表示一个字符串有一个a后面跟着至少一个c或者更多;
# "abc?":表示一个字符串有一个a后面跟着零个或者一个c;
# "a?b+$":表示在字符串的末尾有零个或一个a跟着一个或几个b。
# "abc{2}":表示一个字符串有一个a跟着2个c("abcc");
# "abc{2,}":表示一个字符串有一个a跟着至少2个c;
# "abc{3,5}":表示一个字符串有一个a跟着3到5个c。
# '|',表示“或”操作:
# "hi|hello":表示一个字符串里有"hi"或者"hello";
# "(b|cd)as":表示"bef"或"cdas";
# '.'可以替代任何字符:"a.*[0-9]":表示一个字符串有一个"a"后面跟着多个任意字符和一个数字
# "^.{2}$":表示有任意2个字符的字符串
# 方括号表示某些字符允许在一个字符串中的某一特定位置出现
# "[ab]":表示一个字符串有一个"a"或"b"
# "[a-d]":表示一个字符串包含的'a'到'd'中的一个
# "^[a-zA-Z]":表示一个以字母开头的字符串
# "[0-9]a":表示一个a前有一位的数字
# "[a-zA-Z0-9]$":表示一个字符串以一个逗号后面跟着一个字母或数字结束。
3、正则表达式修饰符 - 可选标志
修饰符 | 描述 |
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |