正则表达式与文件操作

在爬虫开发中,需要把有用的信息从一大段文本中提取出来,正则表达式是最直接的提取方法之一

  • 正则表达式的基本符合
  • 如何在Python中使用正则表达式
  • 正则表达式的提取技巧
  • Python读写文本文件和CSV文件

1.正则表达式

正则表达式是一段字符串,他可以表示一段有规律的信息,Py自带一个正则表达式模块,通过这个模块可以查找、提取、替换一段有规律的信息

使用步骤:

  1. 寻找规律
  2. 使用正则符合表示规律
  3. 提取信息

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()这个方法来获取里面的值。

正则表达式与文件操作插图1

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

正则表达式与文件操作插图2
3-5

3..*和.*?的区别

.*?表示匹配一个能满足要求的最短字符串

我的QQ密码是:1473167199,手机密码是:123456789,银行卡密码是:888888,帮我记住他们

这段话的规律是:密码是:xxxxxx, ,也就是在密码是这三个汉字的后面跟一个英文的冒号,冒号后面是密码,密码后面是英文的逗号,可以构造正则表达式提取密码:

密码是:(.*?),
密码是:(.*),

得出的结果也不同:

不使用问号:
['1473167199,手机密码是:123456789,银行卡密码是:888888']
只有一个元素
使用问号:
['1473167199','123456789','888888']
得出3个元素分别对应原来文本中的每个密码

一句话总结:

①“.*”:贪婪模式,获取最长的满足条件的字符串。
②“.*? ”:非贪婪模式,获取最短的能满足条件的字符串。

版权声明:
作者:RHZ
链接:https://www.rhzhz.cn/?p=313
来源:RHZ | 用文字记录工作和学习生活
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
正则表达式与文件操作
在爬虫开发中,需要把有用的信息从一大段文本中提取出来,正则表达式是最直接的提取方法之一 正则表达式的基本符合如何在Python中使用正则表达式正则表达……
<<上一篇
下一篇>>