正则表达式
正则表达式介绍
正则表达式是一个特殊的字符序列,通常被用来检索、替换那些符合某个模式(规则)的文本。
python中使用re模块。
特点
- 灵活性、逻辑性和功能性非常强
- 可以迅速地用极简单的方式达到字符串的复杂控制
python中的正则表达式
import re
word = 'h230dsdkf349dsd0)' # 取里面的数字
print(re.findall(r'\d+', word)) # r是让转义字符失效不用r就要多加一个\
print(re.sub(r'\d', "@", word))
['230', '349', '0']
h@@@dsdkf@@@dsd@)
正则查找
1. search 方法
import re
word = 'h2303dsdkf349dsd0)' # 取里面的数字
# word.index('3') # 字符串的方法只能找一个字符
result = re.search(r'3\d+', word)
print(result)
# \d表示任意数字 +表示出现一次或多次
result = re.search(r'3\d', word)
print(result)
<re.Match object; span=(2, 5), match='303'>
<re.Match object; span=(2, 4), match='30'>
2. match 方法
match是从字符串的开始匹配
print(re.match(r'3\d+', word))
print(re.match(r'h\d+', word))
None
<re.Match object; span=(0, 5), match='h2303'>
fullmatch 完整匹配
print(re.fullmatch(r'h\d+', word))
print(re.fullmatch(r'h\d+', 'h12312324'))
None
<re.Match object; span=(0, 9), match='h12312324'>
3. findall / finditer 匹配多个
x = re.finditer(r'3\d+', word) # 结果是个迭代器
for i in x:
print(i)
<re.Match object; span=(2, 5), match='303'>
<re.Match object; span=(10, 13), match='349'>
print(re.findall(r'3\d+', word)) # 结果是个列表
['303', '349']
re.Match类型
# re模块的 match / search / fullmatch / finditer 得到的结果都有re.match类型
x1 = re.search(r'\d+', 'ab12cd34ef567g8901')
print(dir(x1))
['__class__', '__class_getitem__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']
print(x1.end()) # 获取匹配到的字符串的结束索引
print(x1.endpos) # 获取整个字符串的长度
print(x1.span()) # 匹配到的字符串的(起始,结束)索引
print(x1.string) # 所查找的完整字符串
print(x1.group()) # 获取匹配到的字符串
4
18
(2, 4)
ab12cd34ef567g8901
12
正则表达式的分组
import re
x1 = re.search(r'b\d+cd\d+ef\d+g\d+', 'ab12cd34ef567g8901')
print(x1.group())
x2 = re.search(r'(b\d+)(cd\d+)(ef\d+)(g\d+)', 'ab12cd34ef567g8901')
print(x2.group())
# 虽然上面2种结果一样,但上面的只有一个分组,下面的有好几个分组
print(x2.group(1))
print(x2.group(2))
print(x2.group(0)) # group(0)等价于group()
b12cd34ef567g8901
b12cd34ef567g8901
b12
cd34
b12cd34ef567g8901
print(x1.groups())
print(x2.groups()) # 拿到所有子分组匹配到的字符串组成的一个元组
()
('b12', 'cd34', 'ef567', 'g8901')
正则表达式使用(?P<name>…) 语法给组命名
x3 = re.search(r'(?P<name1>ab\d+)(?P<name2>cd\d+)(?P<name3>ef\d+)(?P<name4>g\d+)', 'ab12cd34ef567g8901')
print(x3.lastgroup) # 拿到最后一个分组的组名
print(x3.groupdict()) # 以字典的形式保存有组名的分组的数据
name4
{'name1': 'ab12', 'name2': 'cd34', 'name3': 'ef567', 'name4': 'g8901'}
re.compile
可以代替正则规则
patten = re.compile(r"ab\d+")
print(patten.search('ab1234'))
正则修饰符
print(re.search(r'a', 'ABC'))
print(re.search(r'a', 'ABC', re.I)) # re.I就是正则修饰符
None
<re.Match object; span=(0, 1), match='A'>
正则修饰符 | 意思 | |
---|---|---|
re.A | re.ASCII | 只匹配ASCII |
re.I | re.IGNORECASE | 进行忽略大小写匹配 |
re.L | re.LOCALE | 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配 |
re.M | re.MULTILINE | 设置以后,样式字符 ‘^’ 匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符 ‘$’ 匹配字符串尾,和每一行的结尾(换行符前面那个符号)。默认情况下,’^’ 匹配字符串头,’$’ 匹配字符串尾。 |
re.S | re.DOTALL | 让 ‘.’ 特殊字符匹配任何字符,包括换行符 |
re.X | re.VERBOSE | 当一个行内有 # 不在字符集和转义序列,那么它之后的所有字符都是注释 |
正则匹配规则
- 数字和字母表示它本身,没有特殊含义
- \ 有特殊含义,用来转义
- 大多数字母前加\ 转义后,会有特殊含义
- 绝大多数标点符号都有特殊含义
- 如果想要表示标点符号本身,则需要用\ 转义字符
转义字母的特殊含义
模式 | 描述 |
---|---|
\w | 匹配数字字母下划线 |
\W | 匹配非数字字母下划线 |
\s | 匹配任意空白字符,等价于 [ \n\r\f]。 |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]。 |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\n, \t, 等。 | 匹配一个换行符。匹配一个制表符, 等 |
\1…\9 | 匹配第n个分组的内容。 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
print(re.findall(r'\s', 'hello world, hello python'))
[' ', ' ', ' ']
标点符号的特殊含义
‘_’ 不再被转义
只有在正则表达式中具有特殊含义的字符才会被转义。 因此, ‘!’, ‘"’, ‘%’, “’”, ‘,’, ‘/’, ‘:’, ‘;’, ‘<’, ‘=’, ‘>’, ‘@’ 和 “`” 将不再会被转义。