正则就是字符串处理的瑞士军刀
之前我们是通过if判断来匹配某个字符串,不灵活,太死板了
手机号码匹配,就是有些网站是通过手机号登录的,就是通过这个正则来实现的
电子邮件等应用场景
使用正则就必须使用这个re模块,内置模块,直接导入,不需要下载
re模块核心的函数
1、re.findall(pattern,string,flags=0)
功能:在整个字符串中查找所有匹配项,返回列表(包含所有匹配结果)
场景:批量提取文本中的目标内容(如所有邮箱、所有数字)
参数详解:
-
pattern 就是匹配的内容,要找的这个内容
-
string 匹配的对象,就是从这个对象里面找我需要的内容,必须是字符串
import res1 = "pythonqwerpython"result = re.findall("python",s1)
print(result)# 输出结果为,返回的是一个列表
['python', 'python']# 匹配失败,返回的是一个空列表result = re.findall("qc",s1)
print(result)# 输出结果为
[]
2、re.match(pattern,string,flags=0)
功能:从字符串开头匹配正则表达式,仅返回第一个结果
- 只会从最开头开启匹配,只管最前面,匹配的内容在中间也会匹配失败,必须在开头
返回值:匹配成功返回的是一个match对象,失败返回none
match对象常用的方法:
-
span(): 返回匹配的起始和结束的索引,也就是匹配到第一个的切片(元组:(start,end))
-
group(): 返回匹配的整个字符串,就是返回匹配的内容
-
groups(n): 返回第n个分组的内容(n从1开始)
s2 = "pythonqwerpython"result = re.match("python",s2)print(result)
# 返回的是一个对象
<re.Match object; span=(0, 6), match='python'>print(result.span())# 返回第一个匹配到内容的切片
(0,6)print(result.group())# 返回匹配到的内容
python# match是从开头就开始匹配的,非常精确的匹配s2 = "qwerpython" result = re.match("python",s2)print(result)# 输出结果为,没有匹配到,从开头就开始匹配了
None
3、re.search(pattern,string,flags=0)
功能:在整个字符串查找第一个匹配项(不限制开头了)
返回值:也是返回一个匹配对象,
区别match, match仅匹配开头,search匹配任意位置,就是从头匹配到尾
方法:
-
span()
-
group()
s4 = "pythonqwertpython"print(re.search("python",s4))# 返回一个对象
<re.Match object; span=(0, 6), match='python'>print(re.search("python",s4).group())# 返回第一个匹配的到的内容# 和match最不同的方式,从头开始匹配到尾,输出第一次匹配到的内容s5 = "qwerpython"
print(re.search("python",s5).group())# 输出结果为
python
上面匹配的内容都是写死的,因此我们需要使用正则来实现这个灵活性
元字符和量词
元字符是正则表达式的语法符号,量词用于控制字符重复次数,结合使用
-
查什么
-
差多少
普通字符(直接匹配)
字母、数字,下划线等普通字符,直接匹配本身
示例;"abc" 匹配 字符串中的"abc", 123 匹配 123, "_" 匹配 "_"
核心特殊元字符(需要掌握)
元字符
查什么,就是匹配的内容
| 元字符 | 含义 | 示例 |
|---|---|---|
. |
匹配任意单个字符(除了换行符\n) | "a.b"匹配aab,a和b之间任意字符都匹配 |
^ |
匹配字符串开头 | ^abc匹配abc123,不匹配xabc |
$ |
匹配字符串末尾的 | n$ 匹配字符串末尾是n的 |
[] |
匹配括号里面任意一个字符,支持范围[a-z],排除[^a-z] | "[abc]"匹配a,b,c三个字符 |
[^] |
否定字符集,匹配括号外的任意字符 | [^abc] 匹配除了a/b/c外的字符 |
() |
分组:将括号内内容视为整体,可用于提取子串、反向引用 | "(ab)+" 匹配 "ab"/"abab";"(a)(b)" 可通过 \1/\2 引用 |
| |
或:匹配左右任意一个表达式(优先级较低,需配合分组使用) | "a|b" 匹配 "a"/"b";"(ab)|(cd)" 匹配 "ab"/"cd" |
\ |
转义字符:将特殊字符转为普通字符(如 \. 匹配 .) |
"\." 匹配 ".";"\*" 匹配 "*";"\\n" 匹配换行符 |
\d |
等价于[0-9],匹配任意数字 | \d+ 提取字符串中所有数字 |
\D |
等价于[^0-9]匹配非数字 | \D+ 提权字符串非数字字符内容 |
\s |
等价于[\t\n\r\f] 匹配看=空白字符(空格,制表符,换行等) | \s匹配字符串中的空格 |
\S |
等价于[^\t\n\t\f] 匹配非空白字符 | \S 匹配非空白字符 |
\w |
等价于[a-zA-Z0-9_] 匹配字母,数字,下划线 | \w+ 匹配单词(含下划线) |
\b |
- | 匹配单词边界(单词与非单词的分隔) |
\B |
- | 匹配非单词边界 |
元字符案例
p1 = "abcdefgqwer"print(re.findall(".",p1)) # 在整个字符串中匹配任意的单个字符,也就是全部匹配到了# 返回结果为
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'q', 'w', 'e', 'r']
量词(控制重复次数)
量词
查多少次
表示匹配前一个字符出现的次数的控制,支持贪婪和非贪婪模式,是正则的核心特性之一
元字符和量词配合使用,效果最佳
默认所有量词都是贪婪,但是量词后面加上一个? 就是非贪婪,拿到第一个立刻停,绝不多拿
| 量词类型 | 语法 | 贪婪/非贪婪 | 含义 | 示例(匹配 a) |
|---|---|---|---|---|
| 零次或多次 | * |
贪婪 | 重复 0 次或多次(优先最多) | a* 匹配 ""/"a"/"aaa" |
| 零次或多次 | *? |
非贪婪 | 重复 0 次或多次(优先最少) | a*? 优先匹配 "" |
| 一次或多次 | + |
贪婪 | 重复 1 次或多次(优先最多) | a+ 匹配 "a"/"aaa" |
| 一次或多次 | +? |
非贪婪 | 重复 1 次或多次(优先最少) | a+? 优先匹配 "a" |
| 零次或一次 | ? |
贪婪 | 重复 0 次或 1 次(优先 1 次) | a? 匹配 ""/"a" |
| 零次或一次 | ?? |
非贪婪 | 重复 0 次或 1 次(优先 0 次) | a?? 优先匹配 "" |
| 精确次数 | {n} |
无(固定) | 必须重复 n 次 | a{3} 匹配 "aaa" |
| 范围次数 | {m,n} |
贪婪 | 重复 m~n 次(优先 n 次) | a{2,4} 匹配 "aa"/"aaa"/"aaaa" |
| 范围次数 | {m,n}? |
非贪婪 | 重复 m~n 次(优先 m 次) | a{2,4}? 优先匹配 "aa" |
| 最少次数 | {m,} |
贪婪 | 至少重复 m 次(无上限,优先最多) | a{2,} 匹配 "aa"/"aaa"… |
| 最多次数 | {,n} |
贪婪 | 最多重复 n 次(0~n 次,优先 n 次) | a{,3} 匹配 ""/"a"/"aaa" |
量词实战
主要就是这些符号的了解,符号的实战
r核心作用就是让字符串里的\表示普通字符,不被当成转义字符
r"\n"
分组
总结
re模块函数总结
re.findall 在整个字符串找到所有匹配的内容,返回一个列表
re.search 在整个字符串找到第一次匹配的内容,返回一个匹配的对象
re.match 从头就开始匹配,不符合就返回none,匹配成功就返回匹配的对象
