Python基础-正则表达式

一、正则表达式介绍

1.正则表达式一种用来匹配字符串的强有力武器,用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,就认为它“匹配”了,否则,该字符串就是不合法的

2.正则表达式是高级的字符串匹配处理方式

3.正则表达式的原理:通过描述匹配内容的类型和长度来获取字符串当中的指定字符

二、正则表达式的划分

1.对类型的描述

(1)原样匹配

通常原样匹配会结合其他匹配一起出现

r''或者r"",表示中间的部分就是全部的原含义,没有任何的特殊含义

原样匹配,通常会结合其他匹配一起出现

import re

str_ = "suner suner"
str_1 = re.findall(r"u",str_)
print(str_1)  # 结果:['u', 'u']

(2). 匹配,匹配所有非换行的字符

import re

str_ = "suner yao xue xi"
str_1 = re.findall(r".", str_)
str_2 = re.findall(r"..", str_)
str_3 = re.findall(r"...", str_)
str_4 = re.findall(r"....", str_)

print(str_1)  # 结果:['s', 'u', 'n', 'e', 'r', ' ', 'y', 'a', 'o', ' ', 'x', 'u', 'e', ' ', 'x', 'i']
print(str_2)  # 结果:['su', 'ne', 'r ', 'ya', 'o ', 'xu', 'e ', 'xi']
print(str_3)  # 结果:['sun', 'er ', 'yao', ' xu', 'e x']
print(str_4)  # 结果:['sune', 'r ya', 'o xu', 'e xi']

(3)\ 转义,将特殊字符的特殊含义转义掉,变为一个普通的匹配字符串

import re

str_ = "zhe ge shi 20.000.00"
str_1 = re.findall(r"\.", str_)  
print(str_1)  # 结果:['.', '.']

(4)\d 匹配数字

规则:在正则匹配当中,大写和小写匹配的内容是相反的

import re

str_ = "zhe ge 20000 na ge 5000"
str_1 = re.findall(r"\d", str_)   # 匹配一个数字
str_2 = re.findall(r"\d\d", str_)  # 匹配连续两个数字

print(str_1)  # 结果:['2', '0', '0', '0', '0', '5', '0', '0', '0']
print(str_2)  # 结果:['20', '00', '50', '00']

(5)\D 匹配非数字

import re

str_ = "zhe $$ 20000 na **a5000"
str_1 = re.findall(r"\D", str_)   # 匹配一个非数字
str_2 = re.findall(r"\D\D", str_)  # 匹配连续两个非数字

print(str_1)  # 结果:['z', 'h', 'e', ' ', '$', '$', ' ', ' ', 'n', 'a', ' ', '*', '*', 'a']
print(str_2)  # 结果:['zh', 'e ', '$$', ' n', 'a ', '**']

(6)\w 匹配数字、字母,下划线

import re

str_ = "zhe $$ 20000 _na ** a_ 5000_"
str_1 = re.findall(r"\w", str_)   # 匹配一个数字,字母,下划线
str_2 = re.findall(r"\w\w", str_)  # 匹配两个数字,字母,下划线

print(str_1)  # 结果:['z', 'h', 'e', '2', '0', '0', '0', '0', '_', 'n', 'a', 'a', '_', '5', '0', '0', '0', '_']
print(str_2)  # 结果:['zh', '20', '00', '_n', 'a_', '50', '00']

(7)\W 匹配非数字、字母,下划线

import re

str_ = "zhe $$¥ 20000 _na ** a_ 5000_"
str_1 = re.findall(r"\W", str_)   # 匹配一个非数字、字母,下划线
str_2 = re.findall(r"\W\W", str_)  # 匹配两个非数字、字母,下划线

print(str_1)  # 结果:[' ', '$', '$', '¥', ' ', ' ', ' ', '*', '*', ' ', ' ']
print(str_2)  # 结果:[' $', '$¥', ' *', '* ']

(8)\s 匹配所有空格,但是包含\t,\n

import re

str_ = "suner\n yao hao hao xue xi\t"
str_1 = re.findall(r"\s", str_)   # 按长度为1(包含\n\t)匹配空格
str_2 = re.findall(r"\s\s", str_)  # 按长度为2(包含\n\t)匹配空格

print(str_1)  # 结果:['\n', ' ', ' ', ' ', ' ', ' ', '\t']
print(str_2)  # 结果:['\n ']

(9)\S 匹配所有非空格

import re

str_ = "suner\n you 200 %% *&¥\t"
str_1 = re.findall(r"\S", str_)   # 按长度为1匹配非空格
str_2 = re.findall(r"\S\S", str_)  # 按长度为2匹配非空格

print(str_1)  # 结果:['s', 'u', 'n', 'e', 'r', 'y', 'o', 'u', '2', '0', '0', '%', '%', '*', '&', '¥']
print(str_2)  # 结果:['su', 'ne', 'yo', '20', '%%', '*&']

(10)[] 匹配指定的任意一个元素

import re

str_ = "suner hao hao xue xi ya"
str_1 = re.findall(r"[e]", str_)  # 匹配"e"
str_2 = re.findall(r"[a][o]", str_)  # 匹配"ao"
str_3 = re.findall(r"[ao]", str_)  # 匹配"a"或"o"

print(str_1)  # 结果:['e', 'e']
print(str_2)  # 结果:['ao', 'ao']
print(str_3)  # 结果:['a', 'o', 'a', 'o', 'a']

(11)[-] 匹配指定范围里的任意一个元素

import re

str_ = "suner a 2y 1234589 "
str_1 = re.findall(r"[1-5]", str_)  # 匹配1-5之间的
str_2 = re.findall(r"[a-f]", str_)  # 匹配a-f之间的
str_3 = re.findall(r"[1-5][s-z]", str_)  # 匹配第一个为1-5之间并且第二个为a-f之间的

print(str_1)  # 结果:['2', '1', '2', '3', '4', '5']
print(str_2)  # 结果:['e', 'a']
print(str_3)  # 结果:['2y']

(12)[^] 对中括号当中的所有元素取非,取反

import re

str_ = "suner hao hao"
str_1 = re.findall(r"[^un]", str_)  # 匹配非un的元素
str_2 = re.findall(r"[^un][^ao]", str_)  # 匹配第一个为非un,第二个为非ao的元素

print(str_1)  # 结果:['s', 'e', 'r', ' ', 'h', 'a', 'o', ' ', 'h', 'a', 'o']
print(str_2)  # 结果:['su', 'er', ' h', 'o ']

(13)| 匹配符号两边任意一边

import re

str_ = "suner hao hao"
str_1 = re.findall(r"u|h", str_)  # 匹配所有u或者h

print(str_1)  # 结果:['u', 'h', 'h']

(14)^ 代表开头

import re

str_ = "suner hao hao"
str_1 = re.findall(r"^s", str_)  # 匹配以"s"开头元素
str_2 = re.findall(r"^u", str_)  # 匹配以"s"开头元素

print(str_1)  # 结果:['s']
print(str_2)  # 结果:[]

(15)$ 代表结尾

import re

str_ = "suner hao"
str_1 = re.findall(r"o$", str_)  # 匹配以"o"结尾的
str_2 = re.findall(r"a$", str_)  # 匹配以"a"开头元素

print(str_1)  # 结果:['o']
print(str_2)  # 结果:[]

(16)() 组匹配,会将组之外的内容作为匹配条件

import re

str_ = "su1 su1 ner hao 123 hao ** 8956 _5"

str_1 = re.findall(r"(\w\d)", str_)  # 匹配数字、字母、下划线+数字
str_2 = re.findall(r"(\w\D)", str_)  # 匹配数字、字母、下划线+非数字
str_3 = re.findall(r"(\w)\D", str_)  # 匹配一个数,匹配的这个数后面接的是非数字

print(str_1)  # 结果:['u1', 'u1', '12', '89', '56', '_5']
print(str_2)  # 结果:['su', '1 ', 'su', '1 ', 'ne', 'r ', 'ha', 'o ', '3 ', 'ha', 'o ', '6 ']
print(str_3)  # 结果:['s', '1', 's', '1', 'n', 'r', 'h', 'o', '3', 'h', 'o', '6']

(17)(?p<>) 命名分组

命名分组就是给具有默认分组编号的组另外再给一个别名

格式:(?P<name>正则表达式)  # name是一个合法的标识符


2.对数量的描述

(1)* 0到多次

import re

str_ = "sun 678 er"
str_1 = re.findall(r"\d*", str_)  # 匹配0次或者多次数字
str_2 = re.findall(r"\D*", str_)  # 匹配0次或者多次非数字

print(str_1)  # 结果:['', '', '', '', '678', '', '', '', '']
print(str_2)  # 结果:['sun ', '', '', '', ' er', '']

(2)+ 1到多次

import re

str_ = "sun 678 er"
str_1 = re.findall(r"\d+", str_)  # 匹配1次或者多次数字
str_2 = re.findall(r"\D+", str_)  # 匹配1次或者多次非数字

print(str_1)  # 结果:['678']
print(str_2)  # 结果:['sun ', ' er']

(3) 0到1次

import re

str_ = "sun28541"
str_1 = re.findall(r"\d?", str_)  # 匹配0次或者1次数字
str_2 = re.findall(r"\D?", str_)  # 匹配0次或者1次非数字

print(str_1)  # 结果:['', '', '', '2', '8', '5', '4', '1', '']
print(str_2)  # 结果:['s', 'u', 'n', '', '', '', '', '', '']

(4){} 匹配指定次

import re

str_ = "sune28541"
str_1 = re.findall(r"\d{2}", str_)  # 匹配两个都是数字的元素
str_2 = re.findall(r"\D{1,3}", str_)  # 匹配1个或3个非数字

print(str_1)  # 结果:['28', '54']
print(str_2)  # 结果:['sun', 'e']

3.特殊匹配

(1)贪婪匹配

import re

# .* 贪婪匹配,如以第一个s开头最后一个r结尾,直至匹配到最后一个
# .*? 反贪婪匹配,如以第一个s开头第一个r结尾,即匹配到了就不匹配了
str_ = "suner285ner41ner"
str_1 = re.findall(r"s(.*)r", str_)
str_2 = re.findall(r"s(.*?)r", str_)

print(str_1)  # 结果:['uner285ner41ne']
print(str_2)  # 结果:['une']

(2)re.I 忽略大小写匹配

import re

str_ = "suneruNerUnerUN"
str_1 = re.findall(r"un", str_)  # 默认不忽略大小写
str_2 = re.findall(r"un", str_, re.I)   # 设置忽略大小写

print(str_1)  # 结果:['un']
print(str_2)  # 结果:['un', 'uN', 'Un', 'UN']

(3)re.M 忽略换行(默认就是忽略换行,匹配所有字符)

import re

str_ = "suner\nyao\nhao\nhao\nxue\nxi"
str_1 = re.findall(r"ao", str_)  # 默认
str_2 = re.findall(r"ao", str_, re.M)   # 默认设置忽略换行

print(str_1)  # 结果:['ao', 'ao', 'ao']
print(str_2)  # 结果:['ao', 'ao', 'ao']

(4)re.S 

如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始,不会跨行。

使用re.S参数以后,正则表达式会将这个字符串作为一个整体,将“\n”当做一个普通的字符加入到这个字符串中,在整体中进行匹配。

import re

str_ = """
    suner
    hen
    nuli
"""
str_1 = re.findall(r"^.", str_)  
str_2 = re.findall(r"^.", str_, re.S)   

print(str_1)  # 结果:[]
print(str_2)  # 结果:['\n']

4.匹配方法

Compile 匹配模板,这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象

import re

# compile 匹配模板,先定义出匹配模板,在匹配字符
str_ = "suner 20190226"
compile_num = re.compile(r"\d")     # 定义匹配模板
str_1 = compile_num.findall(str_)   # 进行匹配

compile_not_num = re.compile(r"\D")     # 定义匹配模板
str_2 = compile_not_num.findall(str_)   # 进行匹配

print(str_1)  # 结果:['2', '0', '1', '9', '0', '2', '2', '6']
print(str_2)  # 结果:['s', 'u', 'n', 'e', 'r', ' ']

(1)match匹配

从开头进行匹配,匹配一次,如果没有遇到,就返回None

import re

str_ = "suner 20190226"
str_1 = re.match(r"\d", str_)  # 从开头匹配,没有就返回None
str_2 = re.match(r"\w", str_)  # 从开头匹配,有就返回匹配对象

print(str_1)  # 结果:None
print(str_2)  # 结果:<_sre.SRE_Match object; span=(0, 1), match='s'>
print(str_2.group())  # 结果:s ,取出匹配值用group()方法

(2)search匹配

从左往右进行匹配,匹配一次,如果没有遇到,就返回None

import re

str_ = "suneur 20190226"
str_1 = re.search(r"y", str_)  # 从左往右匹配1次,没有就返回None
str_2 = re.search(r"u", str_)  # 从左往右匹配1次,有就返回匹配对象

print(str_1)  # 结果:None
print(str_2)  # 结果:<_sre.SRE_Match object; span=(1, 2), match='u'>
print(str_2.group())  # 结果:u

(3)split匹配

类似字符串的split

import re

str_ = "sun2019 eun 23er 0226"
str_1 = re.split(r"\d", str_)  # 以数字分隔
str_2 = re.split(r"\D", str_)  # 以非数字分隔

print(str_1)  # 结果:['sun', '', '', '', ' eun ', '', 'er ', '', '', '', '']
print(str_2)  # 结果:['', '', '', '2019', '', '', '', '', '23', '', '', '0226']

(4)sub匹配

类似字符串的replace

import re

str_ = "sun2019 eun 23er 0226"
str_1 = re.sub(r"\d", "8", str_)  # str_中的所有数字替换为“8”
str_2 = re.sub(r"\D", "s", str_)  # str_中的所有非数字替换为“s”

print(str_1)  # 结果:sun8888 eun 88er 8888
print(str_2)  # 结果:sss2019sssss23sss0226

猜你喜欢

转载自blog.csdn.net/qq_39620483/article/details/87910824