吾知网

标题: Python爬虫-正则 [打印本页]

作者: jekeyhui99    时间: 2019-1-24 15:14
标题: Python爬虫-正则
前言
想说正则的知识点并不多,需要思考地方却不少。python里提取数据的方式很多,但私以为掌握那些中的某一个的同时,一定要兼顾正则。主观推崇原因有二,一:re是python的基本库,不需要额外安装且解析速度快;二:正则能做到xpatn、BeautifulSoup、PyQuery可以做到的;正则还是能做到它们做不到的。

使用
import re
match,正则中最基本的函数,用法:
result = re.match(pattern, 需要区配的字符串)
result.group()取出被区配到的部分
演示语法的时候,基本会用match函数演示。match区配的过程是:从左到右区配,直到出现不满足规则的时候停止
语法
表示字符
字符        功能
.        区配任意一个字符(除\n)
[]        区配[]中列举的字符
\d        区配数字,0-9
\D        区配非数字
\s        区配空白,(包含空格和Tab键)(\t \n 空格)
\S        区配非空白
\w        区配单词字符,a-z,A-Z,0-9,_
\W        区配非单词字符
1. 点表示任意字符,所以返回h


中括号是列举的意思,表示只要满足其中任意一个就行


\d表示数字,等价于[0-9]

\s表示制表符,空格,换行;这里用"""包裹的字符串来演示,因为"""里,字符串可以保存样式,即可以包含换行的内容,所以最后返回换行符

\w的使用基本上可以举一反三了,包括其大写字符的实现效果。规则很好记忆:d是digit,s是space,w是word
表示个数
字符        功能
*        限定前一个字符出现0次或n次
+        限定前一个字符出现1次或者n次
?        限定前一个字符出现0次或1次
{m}        限定前一个字符出现m次
{m,}        限定前一个字符至少出现m次
{m,n}        限定前一个字符出现m到n次
1. 前面表示字符,这里是表示个数,在没有明确说明个数的情况下默认一个;其次,表示个数的符号总是修饰它左边的字符
2. *表示被修饰字符出现0次或n次,所以一直到逗号出现,不满足规则了停止,返回区配到的内容,即为hello


表示边界
字符        功能
^        表示字符串开头
$        表示字符串结尾
\b        表示单词的边界
\B        表示非单词边界
1. 需要说名的是^是放在被修饰符的左边,而$放在被修饰符的右边;且如果^在中括号中出现,表示取反的意思
2. 这个规则得分五个部分理解:^\d*表示以数字开头,并且之后可以有0或n个数字;@就表示区配@;中间的\w*表示允许0个或n个单词赐福;.表示任意字符,这里区配邮箱号中的点;\w*$表示存在多个单词字符,并且以单词字符结尾

3. $应该慎用,因为你极可能因此拿不到返回。它指定的是被区配的字符串的末尾,这样说很难理解,看看下面几个示例

我原意是区配邮箱前面的数字,然后区配@符,\w*表示任意个数的单词字符,并且以此结尾。所以根据这个逻辑,料想应该会返回578306307@qq,毕竟小圆点出现后就不再满足要求。然而事实是——没有返回值。这是因为使用$应该以被区配的字符串的结尾作为标准,在这个标准满足之前,中间不能出现任何区配失败,不然返回空
我吉岛吉岛啦,这样长串的句子拗口也难理解,所以上图吧。

【72】可以返回完整的邮箱,为什么【73】失败呢?因为在【73】中标志了要单词字符结尾,然而被区配的字符串在单词字符结尾之前(也就是m出现之前),还有两个字符co没有区配,所以返回空,如果我们删除co,就会有结果了
【74】没结果【75】有结果也是同样的道理,好好对比理解吧!
4. b是border边界的意思。
放在最右侧时,饰其左边的单词字符,表示什么字母结尾的单词

如果放在最左边,修饰右边的单词字符,表示什么字母开头的单词


区配分组
字符        功能
|        “或”,表示符合左右任意一个都可以
(ab)        将括号中字符作为一个分组
\num        引用分组num区配到的字符串
(?P<name>)        分组起别名
(?P=name)        引用别名为name分组区配到的字符串
1. |即“或”运算
2. 用括号表示分组,方便取出;这样一来,我们可以拿出我们想要的部分了

3. \num的使用如下,即从左到右,每个分组依次默认为123……,在后面需要引用的时候就用\num来代替

3. 如果分组太多,一个一个的数会很麻烦,所以正则引进了分组别名的方法,并可以通过指定的语法实现引用


也可以通过别名直接取出分组部分


re的高级用法
search:与match不同,match是从左到右,必须挨个符合;而search表示只要被区配的字符串中有符合的就返回,但是,只返回第一次满足要求的内容。如下示例,返回qq而不返回com


findall():返回被区配字符串中所有的符合要求的内容,返回列表型


sub():将区配到的内容,按照指定的方式替换(批量处理)


也可以通过自定义函数处理。默认需要传参,此时传进来的参数是个对象,需要group()取出区配到的内容,然后做需要的处理,并且return返回


贪婪与非贪婪
python中的正则,默认贪婪模式。表示在区配过程中,会尽可能多的去区配内容。如果需要关闭贪婪模式,加上一个?符号


注意项
这些特殊字符,需要反斜杠转义\ . ^ $ ? + * {} [] () |
在正则里面,存在两种转义,一种是字符串转义,一种姑且称之为“正则转义”吧(我也不知道术语怎么说)
还是上图(一言不合就上图)

如果我们需要打印\n就必须再加一个反斜杠转义,这是大家都知道的,那么使用正则区配的时候是不是只要两个反斜杠就可以了呢?

答案否,如上所说,正则中要进行两次转义。所以修改一下规则就可以成功区配

起初是前面两个反斜杠转义成一个反斜杠,后面两个反斜杠转义成一个反斜杠,此时会有两个反斜杠,再次转义成一个。所以有了上图的结果
建议字符串和正则规则都加上r,减少考虑字符串转义的麻烦
---------------------
作者:有关心情
来源:CSDN
原文:https://blog.csdn.net/qq_41359051/article/details/80711697





欢迎光临 吾知网 (http://5g99.com/bbs/) Powered by Discuz! X3.2