在爬虫开发中,需要把有用的信息从一大段文本中提取出来,正则表达式是最直接的提取方法之一
- 正则表达式的基本符合
- 如何在Python中使用正则表达式
- 正则表达式的提取技巧
- Python读写文本文件和CSV文件
1.正则表达式
正则表达式是一段字符串,他可以表示一段有规律的信息,Py自带一个正则表达式模块,通过这个模块可以查找、提取、替换一段有规律的信息
使用步骤:
- 寻找规律
- 使用正则符合表示规律
- 提取信息
1.点号''.''
一个点号可以替代除了换行符以外的任何一个字符,包括但不限于英文字母、数字、汉字、英文标点符号和中文标点符号:
rhzsname
rhz123name
rhz我是谁me
rhz你好啊me
rhz"你好"me
这些字符串前3个字符都是''rhz''后两个字符都是''me'',只有中间两个字符不同。若使用点号来表示,那么全都可以变成rhz...me的形式,中间有多少个字就用几个点
2.星号”*“
一个星号可以表示他前面的一个子表达式(普通字符、另一个或几个正则表达式符号)0次到无限次:
碎银几两
碎银几两两
碎银几两两两
碎银几两两两两
可用星号表示无限个两
碎银几两*
如果星号的前面是一个点号:
如:碎.*两
他可以表示在'碎'和'两'之间出现任意多个除了换行符以外的任意字符:
碎银几两
碎掉的银子几两
碎掉的money=999银子有几两
3.问号"?"
问号表示他前面的子表达式0次或者1次。这里的问号是英文问号
我爱你。
我爱你鸭。
在汉字'你'和" 。"之间有0个或者1个鸭字,可以使用问号表示:
我爱你鸭?。
问号与点号星号配合构成 “.*?” 。通过正则表达式来提取信息的时候,用到最多的也是这个组合。
你吗
你快乐吗
你快乐是因为我吗
你会1+1=2吗
你areaniceman吗
可以用以下这个正则表达式来表示:
你.*?吗
.*获取全局最长的字符串,.*?获取局部最长尽可能地短
4.反斜杠“\”
反斜杠在正则表达式中不能单独使用,甚至不能在PY中单独使用,反斜杠需要和其他字符配合起来使用把特殊符号变成普通符号,把普通符号变成特殊符号(在正则表达式里面很多符号都有特殊意义,可使用反斜杠来把它当作普通符号使用)
我的密码是*12345*不包括最外层星号。
可以用反斜杠放在星号前面把星号变成普通符号:
我的密码是\*.*\*不包括最外层星号。
而不是
我的密码是*.**不包括最外层星号。
不可以直接用星号来匹配星号
反斜杠也可以把普通符号变成特殊符号:
转义字符
n---->\n-->换行符 \\-->普通反斜杠
\t-->制表符 \d----->数字
\'-->单引号 \"--->双引号
在使用反斜杠后,反斜杠和它后面的一个字符构成一个整体,因此应该将“\n”看成一个字符,而不是两个字符。
5.数字"\d"
虽然"\d"要看做是一个正则表达式符号整体,如果要提取两个数字可以使用\d\d;如果要提取3个数字,可以使用\d\d\d。使用*来表示一个任意位数的数字。
是12314124,请记住
是23123123,请记住
是2312,请记住
全部可用
是\d*,请记住
来表示
6.小括号"()"
小括号可以把括号里面的内容提取出来,前面讲到的符号仅仅能让正则表达式"表示"一串字符串。如果要从一段字符串中提取出一部分的内容需要使用小括号
我的密码:12321312addc你帮我记住
若正则表达式写作: :.*?你 时:
:12321312addc你
通常只想要密码部分,所以使用括号:
:(.*?)你
得到
12321312addc
2.在Python中使用正则表达式
Python的正则表达式模块名字为:"re":
import re
1.findall
Python的正则表达式模块包含一个findall方法,它能够以列表的形式返回所有满足要求的字符串
findall的函数原型:
re.findall(pattern,string,flags=0)
- pattern--->正则表达式
- string----->原来的字符串
- flags------>一些特殊功能的标志
findall的结果是一个列表,包含了所有的匹配到的结果。如果没有匹配到的结果,就会返回空列表
当需要提取某些内容的时候,请使用小括号将这些内容括起来,确保信息的准确
如果包含多个"(.*?)"返回:

返回的依然是一个列表,但是列表里的元素变为了元组,元组里第一个元素是账号,第二个元素是密码
在实际使用正则表达式的过程中,中英文标点符号混淆常常会导致各种问题。特别是冒号、逗号和引号,虽然中英文看起来非常相似,但实际上中文冒号和英文冒号是不一样的,中文逗号和英文逗号也是不一样的。在某些字体里面,这种差异甚至无法察觉,因此在涉及正则表达式中的标点符号时,最好直接复制粘贴,而不要手动输入。
flags这个参数是可以直接省略的,当不省略的时候具有一些辅助功能,例如忽略大小写、忽略换行符等。如忽略换行符:
rhz = """我是rhz,我的QQ是:147
3167199,"""
account_findall_noflag = re.findall('QQ是:(.*?),',rhz)
account_findall_flag = re.findall('QQ是:(.*?),',rhz,re.S)
print('不使re.S的时候:{}'.format(account_findall_noflag))
print('使用re.S的时候:{}'.format(account_findall_flag))
输出
不使re.S的时候:[]
使用re.S的时候:['147\n3167199']
要匹配的内容存在换行符“\n”。要忽略换行符,就需要使用到“re.S”这个flag。
2.search
search()的用法和findall()的用法一样,但是search()只会返回第一个满足要求的字符串,一旦找到符合要求的内容,即刻停止查找。search()的函数原型:
re.search(pattern,string,flags=0)
对于结果如果匹配成功,则是一个正则表达式的对象;如果没有匹配到任何数据,则需要通过.group()这个方法来获取里面的值。

只有在.group()里面的参数为1的时候,才会把正则表达式里面的括号中的结果打印出来。
.group()的参数最大不能超过正则表达式里面括号的个数。参数为1表示读取第1个括号中的内容,参数为2表示读取第2个括号中的内容,以此类推,如图3-5所示。

3..*和.*?的区别
.*?表示匹配一个能满足要求的最短字符串
我的QQ密码是:1473167199,手机密码是:123456789,银行卡密码是:888888,帮我记住他们
这段话的规律是:密码是:xxxxxx, ,也就是在密码是这三个汉字的后面跟一个英文的冒号,冒号后面是密码,密码后面是英文的逗号,可以构造正则表达式提取密码:
密码是:(.*?),
密码是:(.*),
得出的结果也不同:
不使用问号:
['1473167199,手机密码是:123456789,银行卡密码是:888888']
只有一个元素
使用问号:
['1473167199','123456789','888888']
得出3个元素分别对应原来文本中的每个密码
一句话总结:
①“.*”:贪婪模式,获取最长的满足条件的字符串。
②“.*? ”:非贪婪模式,获取最短的能满足条件的字符串。
文章评论