码迷,mamicode.com
首页 > 编程语言 > 详细

Python 正则表达式 (python网络爬虫)

时间:2018-02-01 23:13:33      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:www   左右   全面   组合键   依赖   区间   自身   eclipse   返回   

  昨天 2018 年 01 月 31 日,农历腊月十五日。20:00 左右,152 年一遇的月全食、血月、蓝月将今晚呈现空中,虽然没有看到蓝月亮,血月、月全食也是勉强可以了,还是可以想像一下一瓶蓝月亮洗衣液悬于空上,耳边是"大家好,我是渣渣灰,给大家推荐一款好玩的游戏--贪玩蓝月......" 22:00左右的样子,月亮已经出来了,坐下来写写博客啦。

  对计算机程序员而言,要问当下前沿什么方向最流行?我想在大数据、云计算、人工智能这些方向中,目前位于翘楚的就是大AL(人工智能了),一种产品的流行总是会带动其依赖品的流行。说的就是 Python 语言,近几年的势头Python越Java座于编程语言首位。Python流行不仅是因为人工智能机器学习的支持,其自身也是有原因的,Python语言学习起来很容易、易懂,这不小学课堂都开Python课了么。Python又被称为"胶水语言",与其它的语言的兼容性很好。这也让不少程序员转向了Python,更何况当前的人工智能时代即将来临。

  我最近也在学习Python,说到学习Python极大可能会接触到 爬虫 。关于爬虫,通俗说就是抓取网上数据的机器。涉及到爬虫,就与本文的点 正则表达式 就是分不开了。

  正则表达式:又称为规则表达式,百度百科解释其为通常被用来检索、替换那些符合某个模式(规则)的文本。这就有点像那些暴力破解密码的软件,通过字典一个个组合进行破解。这也是挺考验计算机运算能力的.

  关于Python正则表达式的知识,我也是从视频中学习来的。不知道全面否,大家可以进行评论补充。

  正则表达式有以下特殊字符:
  1) ^ . $ * ? + {2} {2, } {2, 5}
  2) [] [^] [a-z] | ()
  3) \s \S \w \W
  4) [\u4E00-\u9FA5] \d

  我将对每个符号进行讲解,并举以实例。

  打开 Eclipse+Pydev、Pycharm 等可以写Python的IDE(集成开发环境),本人就以 Eclipse+Pydev 为例。

(关于 Pydev 的配置使用可以百度下,关于这个我将在以后会写一篇博文进行补充。) 在编写Python过程避免不少要使用汉字,而在 Eclipse+Pydev 初始状态下要通过Python在屏幕上打印中文是会出现乱码,对此需要:

  在 Eclipse 的 Windows > Preference > Workspace > Text file encoding 修改 Default (GBK)为 Other UTF-8 

  鼠标激活编辑框 按下 Alt + Enter 组合键,在出现的窗口 Resource > Text file encoding 修改 Default 为 Other UTF-8

  在 Eslipse 的 Windows > Preference > General > Content Types 中展开列表中的 Text 选择 Python File ,在下方框 Default encoding 填写上 UTF-8 再点击方框后 Update 应用。同时你可以对 Java Source Flie 也设置 UTF-8 ,如果你需要的话。

  更多详细请转 https://www.cnblogs.com/jackge/archive/2013/05/19/3086944.html

  首先在编辑框中写入

 

#coding:utf-8
import re

 

  声明一下编码 UTF-8 导入正则表达式模块

 

  1). ^ 表示必须以特定的字符开头 如 ^e 则是表示待匹配字符串必须以 e 字符开头

    $ 表示必须以特定的字符结尾 与 ^ 恰恰相反字符放置也是相反 如 $e 则是表示待匹配字符串必须以 e 字符结尾 

    . 表示任意字符 匹配任意字符 表示在待匹配字符串指定位置可以出现任意字符

    * 表示指定字符可以出现任意次 (n >= 0) 如 e* 表达在待匹配字符串中指定位置可以出现任意次数

   就 ^ $ . * 举个粟子吧(match 函数从首字母开始开始匹配,regex_str如果包含line子串,则匹配成功,返回Match对象,失败则返回None,若要完全匹配,line要以$结尾)

#coding:utf-8
import re
#导入正则表达式模块
line = "Hello World"
#待匹配字符串
regex_str = "(^H.*d$)"
if re.match(regex_str, line):
# match 函数  (传入的参数,要匹配的字符串) 
# 从首字母开始开始匹配,regex_str如果包含line子串,则匹配成功,
# 返回Match对象,失败则返回None,若要完全匹配,line要以$结尾。
print True else: print False

 

  运行结果 True 说明匹配成功,^H 以 H 字符开头 、 .* 任意字符出现任意次、d$以 d 字符结尾,以上都满足故 True .

  ? 非贪婪匹配,在正则表达式中匹配是贪婪的,程序会尽可能匹配更多的字符,当然这有时候非我们所愿.为了防止其贪婪匹配,于是 ? 就派上用场了。(group()用来提出分组截获的字符串,()用来分组)

 

#coding:utf-8
import re
#导入正则表达式模块
line = "heedeeehhlhloooooooo world"
regex_str = ".*(h.*h).*"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))
#group()用来提出分组截获的字符串,()用来分组
#结果中本来 ‘heedeeeh‘ ‘hh‘ ‘hhlh‘ 都是满足条件的 #但由于贪婪匹配,尽可能匹配更多的的后面的字符,
#这就匹配到最后一个满足条件的
‘hlh‘

 

  运行结果为: hlh ,那么问题来了 heedeeeh hh hhlh hlh 这样也满足条件同时也先出现,那为什么提取的是 hlh 呢? 原来程序是贪婪匹配的的,程序想尽多可能匹配后面更多的然后就像猴子捡了芝麻丢了西瓜,最后就提取出最后一个符合条件的 hlh ,我们也可以这样理解贪婪匹配就是反向(从右往左)进行匹配,匹配到的第一项就是贪婪的结果了。

  防止贪婪你可以在之前加上 ? 这样满足么?来看看

 

#coding:utf-8
import re
#导入正则表达式模块
line = "heedeeehhlhloooooooo world"
regex_str = ".*?(h.*h).*"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))

  运行结果为 heedeeehhlh 好像不是所料到的结果吧,我只是提取个 heedeeeh 。为么呢,原来到上述一样你正向是非贪婪匹配了,而反向却没有,所以呢只需在后面也加上百贪婪匹配就行了(注意加在后面字符前边 即下代码中 h 前)。运行结果 heedeeeh 就对了。

 

#coding:utf-8
import re
#导入正则表达式模块
line = "heedeeehhlhloooooooo world"
regex_str = ".*?(h.*?h).*"
#注意 加在 h 之前
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))

  + 表示指定字符至少出现一次及一次以上, h+ 就表示在待匹配字符串指定位置出现 h 至少一次以上

  {2} 表示指定字符出现2次, h{2} 就表示在待匹配字符串中指定位置出现 h 两次

 

 

  {2,} 表示指定字符至少出现2次及以上,(注意 , 后面不能留有空格) 数字不固定 如 h{3,} 表示待匹配字符串中指定位置出现3次以上

  {2,6} 表示指定字符出现 2次-6次 之间, 如 h{3,5} 表示在字符串中指定位置出现次数在 3次-5次 之间

  见代码 运行结果 heeh 其它就不演示了,差不多的

 

#coding:utf-8
import re
line = "heehhlhloooooooo world"
regex_str = ".*(he{2,}h).*"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))

 

  2). [adbc] 表示在待匹配字符串中指定位置指定字符是 adbc 中任一个就满足条件

    同时可以写成区间形式 如 [a-z] [0-9] 也可以区间叠加 如 [a-zA-z0-9]

    [^h] 则表示待匹配字符串中指定位置指定字符非 h 就满足条件

    注意: [.] [*] 此[]中的 . * 就不再表示任意字符和出现任意次数 这个就表示它们本身

    看看粟子吧 运行结果为 hloooo0

 

#coding:utf-8
import re
line = "heehhlhloooo0 world"
regex_str = ".*(h[^e][a-z].*[0-9]).*"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))

    | 就是或的关系,(h|r)表示待匹配字符串中指定位置只要出现 h 和 r 中的任一个就符合条件

    () 在之前提到过,用来分组,在本实例中与之搭配用的group()就是用来提出分组截获的字符串 group(1) 就表示截获第1个分组的字符串 当然要有分组即需有 ()

  实例

 

#coding:utf-8
import re
line = "hello365"
regex_str = "((hello|hell0o)365)"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))
    print (match_obj.group(2))

  运行分别输入结果 hello365 hello  group(2)就截获第2个分组中的字符串 即 hello 或 hell0o 中一个

 

 

  3). \s 表示待匹配字符串中指定位置指定字符为空格, 而 \S 则是表示非空格 同样的对单独使用只对指定的单个字符有效 若要多个则需加上 +

    \w 表示待匹配字符串中指定位置指定字符为 a-z A-Z _ 等同于 [a-zA-Z0-9_], \W 则是除去这些字符的其它字符 像 ~ ! @ # $ % ^ & * 

    用实例说话

 

#coding:utf-8
import re
line = "hello world~"
regex_str = "(\wello\sworld\W)"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))

  运行结果 hello world~ 对吧 没毛病

 

  4). \d 表示待匹配字符串中指定位置为数字 [\u4E00-\u9FA5] 则是表示为中文

#coding:utf-8
import re
line = "hello world365嗨"
regex_str = "(hello\sworld\d+[\u4e00-\u9fa5]+)"
match_obj = re.match(regex_str, line)  
if match_obj:
    print (match_obj.group(1))

  运行结果为 hello world365 可以看出 \d 是匹配也出来 [\u4e00-\u9fa5] 也是匹配了出来 不然就不会打印出结果 只是打印结果中不显示中文 我也表示纳闷呢 是更改了编码的原因么?

  好,以上就是我学习Python 网络爬虫中重要的一节正则表达式,可能不是很全面,甚至还有点小问题,更多的可以去菜鸟教程等各大知名资料网查询。本人所写仅供参考。

  对了,关于那个打印结果中为啥中文不显示,期望有人指点一二. /小纠结

 

Python 正则表达式 (python网络爬虫)

标签:www   左右   全面   组合键   依赖   区间   自身   eclipse   返回   

原文地址:https://www.cnblogs.com/notfound/p/8395382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!