16 正则表达式
一、作业解答
def fib(): a=0 b=1 while True: a,b=b,a+b #python特殊的语句,a=b;b=a+b 中间自动用变量保存临时值 yield a myfib=fib() n=10 for i in myfib: if n>100: break print(i) n+=1
二、正式课
(一)正则表达式的概念
正则表达式是一个工具,用于匹配字符串,或用来提取字符串
1、判断一个字符串 是否匹配给定的格式(判断用户帐号是否满足格式)
2、从一个字符串中 按指定格式提取信息(抓取页面中的链接)
例子1 findall方法:
1、findall方法:在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表
import re mymail=re.findall(r'^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com$','284939@qq.com') print(mymail) 结果为:['284939@qq.com']
>>> st 'python111python222' >>> re.findall('python',st) ['python', 'python'] >>> re.findall(r'333',st) []
例子2 match方法 :
re.match 尝试从字符串的起始位置匹配一个模式,匹配成功返回的是一个匹配对象(这个对象包含了我们匹配的信息),如果不是起始位置匹配成功的话,match()返回的是空,
1.可以通过group()提取匹配到的内容
2.可以通过span()提取匹配到的字符下标
注意:match只能匹配到一个
>>> st 'python111python222' >>> re.match(r'python',st) <_sre.SRE_Match object; span=(0, 6), match='python'> >>> re.match(r'111',st) >>> a = re.match(r'python',st) >>> a.group() 'python' >>> a.span() (0, 6)
例子3 search方法:
re.search 扫描整个字符串,匹配成功返回的是一个匹配对象(这个对象包含了我们匹配的信息)
注意:search也只能匹配到一个,找到符合规则的就返回,不会一直往后找
re.match与re.search的区别:
re.match只匹配字符串的开始位置找,如果字符串开始不符合正则表达式,则匹配失败,
re.search:匹配整个字符串,如果一直找不到则,返回是空的,没有结果
>>> st 'python111python222' >>> re.search(r'111',st) <_sre.SRE_Match object; span=(6, 9), match='111'> >>> re.search(r'python',st) <_sre.SRE_Match object; span=(0, 6), match='python'> >>> b = re.search(r'python',st) >>> b.group() 'python' >>> b.span() (0, 6)
例子4 sub方法 :作用是替换
>>> st 'python111python222' >>> re.sub(r'1','3',st) 'python333python222'
两层转译:r 转译一次 \.com 转译一次
注意:如果正则表达戒使用了括号,那么 findall 函数匹配的结果只会是括号中的内容,而不是完整的匹配
一个函数:findall
一些元字符:. * ? + [] \ ^ $ 有特殊的作用
通过()改变findall 的行为
(二)元字符
-
通配元字符 . 点代表任意字符,将获取的内容全部提取出来加入列表。
import re my_string='冯娅同1学是粉3丝会会4长,冯娅8正在6走路。' my_s=re.findall(r'.',my_string) print(my_s) 结果:['冯', '娅', '同', '1', '学', '是', '粉', '3', '丝', '会', '会', '4', '长', ',', '冯', '娅', '8', '正', '在', '6', '走', '路', '。']
import re my_string='冯娅同1学是粉3丝会会4长,冯娅8正在6走路。' my_s=re.findall(r'冯娅..',my_string) print(my_s) 结果:['冯娅同1', '冯娅8正'] 后面两个点,表示后面的两个字符,有几个点,表示加几个字符,前面加也是一样的,有几个点匹配几个字
2、锚点元字符
(1) ^ 代表行首
import re my_string='冯娅同1学是粉3丝会会4长,冯娅8正在6走路。' my_s=re.findall(r'^冯娅',my_string) print(my_s) 结果:['冯娅'] 只匹配以'冯娅'行首开头的,行中的不以匹配。
(2) $ 代表行尾
import re my_string='冯娅同1学是粉3丝会会4长,冯娅8正在6走路' my_s=re.findall(r'走路$',my_string) print(my_s) 结果:['走路']
(3)\b 表示单词的边界
import re my_string='hello world i am happy today,happyend' my_s=re.findall(r'\bhappy\b',my_string) print(my_s) 结果:['happy']
(4) {} 用花括号控制次数。
import re my_string='abbbbbbbbc' my_s=re.findall(r'ab{8}c',my_string) print(my_s) 结果:['abbbbbbbbc'] {8}里面的8表示b重复的次数 import re my_string='abbbbbbbbc' my_s=re.findall(r'ab{2,8}c',my_string) print(my_s) {2,8}可以匹配2-8个b import re my_string='abbbbbbbbc' my_s=re.findall(r'ab{2,}',my_string) print(my_s) 结果:['abbbbbbbb'] 说明:右无穷, import re my_string='abbbbbbbbc' my_s=re.findall(r'ab{,10}',my_string) print(my_s) 结果:['abbbbbbbb'] 说明:左无穷,
重复元字符 ?
贪婪模式:
import re my_string='abbbbbbbbc' my_s=re.findall(r'ab*',my_string) print(my_s) 结果:['abbbbbbbb'] 说明:*代表任意多个{0,} 有多少b匹配多少个 import re my_string='abbbbbbbbc' my_s=re.findall(r'ab+',my_string) print(my_s) 结果:['abbbbbbbb'] 说明:+代表一个或多个 {1,} 至少有一个b import re my_string='abbbbbbbbc' my_s=re.findall(r'ab?',my_string) print(my_s) 结果:[] 说明:?代表 一个或没有 {0,1}
非贪婪模式:
import re my_string='abbbbbbbbc' my_s=re.findall(r'ab*?',my_string) print(my_s) 结果:['a'] import re my_string='abbbbbbbbc' my_s=re.findall(r'ab+?',my_string) print(my_s) 结果:['ab'] import re my_string='abbbbbbbbc' my_s=re.findall(r'ab??',my_string) print(my_s) 结果:['a']
选择元字符
| 代表 可以写两个正则表达式
字符组:范围[...N-M...] 反向字符类[^]
import re my_string='abbbb11232142143342332bbbbc' my_s=re.findall(r'[0-9]{2,8}',my_string) print(my_s) 结果:['11232142', '14334233'] import re my_string='12345' my_s=re.findall(r'[^1]',my_string) print(my_s) 结果:['2', '3', '4', '5']
转义元字符 \
元字符(有特殊含义)
字符字面值(无特殊含义)
某些普通字符(无特殊含义)
特殊功能符(有特殊含义)
(6) * + ?的使用
import re my_string='happy happyend happynewyear hahaha fdfsd' my_s=re.findall(r'happy|hahah|fd',my_string) print(my_s) 结果:['happy', 'happy', 'happy', 'hahah', 'fd'] mystr='abbbbb1234' mymail=re.findall(r'[0-9]',mystr) print(mymail) 结果:['1', '2', '3', '4'] #没有用大括号,表示匹配一个字符, mymail=re.findall(r'[0-9]{3}',mystr) print(mymail) 结果:['123'] #大括号里表示要匹配多少个数字。 mystr='abc abd abe' mymail=re.findall(r'ab[bd]',mystr) print(mymail) 结果:['abd'] 前面是ab,后面匹配一个字符,是[bd]中的一个
中括号代表的是 内容 大括号代表的是 数次
[0-9] 所有的数字
[a-z] 所有的小写字母
[A-Z] 所有的大写字母
[A-Za-z0-9] 所有的字母和数字
[^nm] 反向字符,除了nm以外的所有内容
(三)预定义字符组
预定义字符类 | 说明 | 对等字符类 |
---|---|---|
\d | 任意数字字符 | [0-9] |
\D | 任意非数字字符 | [^0-9] |
\s | 任意空白符 | [\t\n\x0B\f\r] |
\S | 任意非空白符 | [^\t\n\x0B\f\r] |
\w | 任意字符数字字符 | [a-zA-Z0-9] |
\W | 任意非字符数字字符 | [^a-zA-Z0-9] |