一.正则表达式介绍
1.学习爬虫,为什么必须会正则表达式?
有时候,我们爬取一些网页具体内容时,会发现我们只需要这个网页某个标签的一部分内容,或者是这个标签的某个属性的值时,用普通的 xpath 或者css.selector是不能实现我们的想法的,这个时候就必须用到正则表达式去匹配获取。
2.正则表达式官方简介?
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
二.看代码边敲边学
1''' 2author : 赵金辉 3date : 2019.12.7 4goal : 正则表达式 5''' 6 7import re 8 9line = 'zjh123' 10 11# ^a 表示匹配以a开头的字符串(只匹配一次) 12# . 表示该字符可为任意字符(只匹配一次) 13# * 表示前面的字符可以出现任意次(0次或多次)(多次匹配) 14reg_str01 = '^j.*' # 表示以j开头的字符串 15# re.match 函数 16# 第一个参数是匹配的格式 17# 第二参数是要匹配的字符串 18# 返回值为:匹配成功,返回match对象,否则返回:None 19 20if re.match(reg_str01,line) : 21 print("匹配成功!") # reg_str = '^j.*' 匹配成功 22else: 23 print("匹配失败!") # reg_str = '^i.*' 匹配失败 24 25 26# 23$ 表示匹配以23结尾的字符串(只匹配一次) 27reg_str02 = '^j.*23$' 28if re.match(reg_str02,line) : 29 print("匹配成功!") # reg_str = '^j.*23$' 匹配成功 30else: 31 print("匹配失败!") # reg_str = '^j.*13$' 匹配失败 32 33 34line01 = 'boooboaobxby' 35# () 内的为 匹配模式,通过 group函数 可以取出匹配结果 36# 正则表达式贪婪匹配模式:从后面(右边)开始匹配 37reg_str03 = '.*(b.*b).*' 38test01 = re.match(reg_str03,line01) 39if test01: 40 print(test01.group(1)) # result : bxb 41else: 42 print("匹配失败!") 43 44# 正则表达式非贪婪匹配模式:从前面(左边)开始匹配 45# ? : 表示从左边开始匹配,匹配到第一个符合模式的内容,即进入模式 46# 47reg_str03 = '.*?(b.*b).*' # 半贪婪匹配 48reg_str04 = '.*?(b.*?b).*' # 非贪婪匹配 49test01 = re.match(reg_str03,line01) 50test02 = re.match(reg_str04,line01) 51if test01 and test02: 52 print(test01.group(1)) # result : boooboaobxb 53 print(test02.group(1)) # result : booob 54else: 55 print("匹配失败!")
day02
1''' 2author : 赵金辉 3date : 2019.12.8 4goal : 正则表达式 5''' 6import re 7line01 = 'boooboaobcxby' 8 9def regtest(reg_str,line = line01): 10 test = re.match(reg_str, line) 11 if test: 12 print(test.group(1)) 13 else: 14 print("匹配失败!") 15 16# + :表示前面的字符,至少出现一次 17reg_str04 = '.*(b.+b).*' # (b.+b)表示b与b之间至少有一个字符 18regtest(reg_str04) # result : bcxb 19 20# {n} : 控制前面字符出现次数 21# a{2} : 表示a出现两次 22# b{3,4} : 表示b至少出现3次,最多出4次 23# c{4,} : 表示c至少出现4次 24reg_str05 = '.*(b.{2}b).*' # (b.{2}b)表示匹配到的b与b之间,只有两字符 25reg_str06 = '.*(b.{3,4}b).*' # (b.{3,6}b)表示匹配到的b与b之间,至少有3个字符,至多有4个字符 26reg_str07 = '.*(b.{4,}b).*' # (b.{8,}b)表示匹配到的b与b之间,至少有4个字符 27regtest(reg_str05) # result : bcxb 28regtest(reg_str06) # result : boaob 29regtest(reg_str07) # result : boaobcxb 30 31# | :表示 或 32# (abc|123) : 表示匹配到 abc 或者 123,都算匹配成功 33reg_str08 = '.*(boo|abc)' 34reg_str09 = '.*(abc|boo)' 35regtest(reg_str08) # result : boo 36regtest(reg_str09) # result : boo 37 38# [] : 表示 里面包含的内容都可以进行匹配,包含内容只有表面字符含义 39# [abcd] : 表示 只要这个字符为 a/b/c/d中的一个都可以匹配成功 40# [0-9] : 表示 只要这个字符在 0-9 这个区间内,都可以匹配成功 41# [^x] : 表示匹配 字符不为 x 42line02 = '电话号:15573563467' 43reg_str10 = '.*(1[3458][0-9]{9}).*' 44reg_str11 = '.*(1[3458][^1]{9}).*' 45regtest(reg_str10,line02) # result : 15573563467 46regtest(reg_str11,line02) # result : 15573563467 47 48# s 表示匹配空格,匹配一次 49# S 表示匹配不是空格的字符,匹配一次 50# w 表示匹配 A-Z、0-9、_ 中的容易字符,匹配一次 51# W 与 w 相反 52# d 表示数字 53# [u4E00-u9FA5] : 表示所有汉字,unicode 编码 54 55def regtest_test(reg_str,line = line01): 56 test = re.match(reg_str, line) 57 if test: 58 print(test.group(1)+':'+test.group(2)+'-'+test.group(3)+'-'+test.group(4)) 59 else: 60 print("匹配失败!") 61 62# 简单实例 63str01 = '张三出生于1997年12月20日' 64str02 = '李四出生于1989-01-20' 65str03 = '王五出生于1997/2/5' 66str04 = '赵六出生于1997.12.20' 67str = [str01,str02,str03,str04] 68# 提取出姓名+出生日期 69# 匹配模式 70reg_str12 = '(.*)出生于(d{4})[.年/-](d{1,2})[.月/-](d{1,2}).*?' 71for i in range(4): 72 regtest_test(reg_str12,str[i]) 73# result : 74# 张三:1997-12-20 75# 李四:1989-01-20 76# 王五:1997-2-5 77# 赵六:1997-12-20
总接一下正则表达式的构成:
正则表达式是由普通字符(列如字符a到z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
①元字符---限定符:
*:匹配前面的子表达式零次或多次。
+:匹配前面的子表达式一次或多次。
?:匹配前面的子表达式零次或一次。
{n}:匹配确定n次。
{n,}:至少匹配n次。
{n,m}:最少匹配n次且最多匹配m次。
②元字符---字符匹配符:
字符匹配符用于匹配某个或某些字符。
[xyz]:字符集合。匹配所包含的任意一个字符。
[^xyz]:负值字符集合。匹配未包含的任意字符。
[a-z]:字符范围。匹配指定范围内的任意字符。
[^a-z]:负值字符范围。匹配任何不在指定范围内的任意字符。
d:匹配一个数字字符。
D:匹配一个非数字字符。
w:匹配包含下划线的任何单词字符。等价于[a-z0-9A-Z_]
W:匹配任何非单词字符。等价于[^a-z0-9A-Z_]
s:匹配任何空白字符。
S:匹配任何非空白字符。
·:匹配除” ”之外的任何单个字符。
③元字符---定位符:
定位符可以将一个正则表达式固定在一行的开始或结束,也可以创建只在单词内或只在单词的开始或结尾处出现的正则表达式。
^:匹配输入字符串的开始位置。
$:匹配输入字符串的结束位置。
:匹配一个单词边界,也就是单词和空格间的位置。
B:匹配非单词边界。