3.正则表达式re

正则表达式是对字符串操作的一种逻辑公式,我们使用正则表达式对字符串进行匹配和过滤

优点:灵活,功能性强,逻辑性强

缺点:上手难,一旦上手,会爱上这个东西

正则匹配在线工具

http://tool.chinaz.com/regex/

元字符

元字符才是正则表达式的灵魂.

     1.字符组

     字符组很简单用[]括起来,在[]中出现的内容会被匹配,列如:[abc] 匹配a或b或c

     如果字符组中的内容过多还可以使用 - ,列如:[a-z]匹配a-z之间的字母[0-9]匹配所有的阿拉伯数字

     2.简单的元字符

.     匹配除换行符以外的任意字符 
\w    匹配字母或数字或下划线
\s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹配一个制表符 \b 匹配一个单词的结尾
^ 匹配字符串的开始 $ 匹配字符串的结尾 \W 匹配非字母或数字或下划线 \D 匹配非数字 \S 匹配非空白符 a|b 匹配字符a或字符b () 匹配括号内的表达式,也表示一个组 [...] 匹配字符组中的字符 [^...] 匹配除了字符组中字符的所有字符

       3.量词

       一次性要匹配多个字符就要使用到量词

*    重复零次或更多次
+    重复一次或更多次 
?    重复零次或一次 
{n}    重复n次 
{n,}    重复n次或更多次 
{n,m}    重复n到m次 

      4.惰性匹配和贪婪匹配

      在量词种*,+,{} 都属于贪婪匹配,就是尽可能多的匹配结果

     .*?尽可能少的匹配,表示惰性匹配

      .*?x的特殊含义 找到下一个x为止

      5.分组

      正则表达式使用()进行分组

      6.转义

      在正则表达式中有许多特殊意义的转义字符,比如\n和\s在匹配一次\n,字符串中要写成\\n,正则表达式中要写成\\\\n这样太麻烦了,就需要用到r'\n'这个概念,正则中就可以使用r'\\n'

匹配邮箱

[a-z0-9-_]+@\w+\.[a-z0-9.]+

匹配手机号

1[3456789][0-9]{9}

匹配生日格式(yyyy-MM-dd)

\d{4}(\_|\-|\/)\d{1,2}\1\d{1,2}

re模块

findall 查找所有,返回list

ret = re.findall("\d","baby电话是137")
print(ret)

search 会进行匹配,但是如果匹配到了结果就会返回这个结果,没有匹配上就返回None

result = re.search("\d","电话号码")
print(result)
# print(result.group())

match 只能从字符串的开头进行匹配

result = re.match("\d+",'137电话号码')
# print(result)
print(result.group())

finditer 和findall差不多,只不过这时返回的是迭代器

ret = re.finditer('\d',"baby123456789")
for i in ret:
    print(i.group())#分组

result = re.finditer("姓名:(?P<name>.*?),爱好:(?P<hobby>.*?)","姓名:宝宝,爱好:女,性格:开朗大方")
for el in result:
    print(el.group("name"),el.group("hobby"))
search和match的区别:
search查找 ,找到的结果就返回 match从头开始匹配

其他操作

# 正则正常操作
result = re.split("\d+","宝宝110来找你了,你收拾收拾去119报道")
print(result)#['宝宝', '来找你了,你收拾收拾去', '报道']

#用正则替换
s = re.sub("\d+","__Sb__","宝宝110来找你了,你收拾收拾去119报道")
print(s)#宝宝__Sb__来找你了,你收拾收拾去__Sb__报道
s = re.subn("\d+","__Sb__","宝宝110来找你了,你收拾收拾去119报道") #替换了多少次
print(s)#('宝宝__Sb__来找你了,你收拾收拾去__Sb__报道', 2)

code = "for i in range(10):print(i)"

c = compile(code ,"","exec")
exec(c)

reg = re.compile(r"\d+")
lst = reg.findall("宝宝110来找你了,你收拾收拾去119报道")
print(lst)

result = re.findall(r"\d+","宝宝110来找你了,你收拾收拾去119报道")
print(result)

lst = re.findall(r"a(?:\d+)c","a123456c")# 把括号python中的分组变成了原来正则表达式中的分组
print(lst)

findall中的坑

ret = re.findall("www.(baidu|oldboy).com","www.oldboy.com")
print(ret)#['oldboy']

ret = re.findall("www.(?:baidu|oldboy).com","www.oldboy.com")
print(ret)#['www.oldboy.com']

split中的坑

ret = re.split("\d+","alex2wusir3yuan")
print(ret)#['alex', 'wusir', 'yuan']

ret = re.split("(\d+)","alex2wusir3yuan")
print(ret)#['alex', '2', 'wusir', '3', 'yuan']

爬取电影天堂

from urllib.request import urlopen
import re
import json

main_url = "https://www.dytt8.net/"
reg = re.compile(r'\[<a href="/html/gndy/dyzz/index.html">最新电影下载</a>\]<a href=\'(?P<url>.*?)\'>', re.S)
son_reg = re.compile(r'<div id="Zoom">.*?◎片  名(?P<name>.*?)<br />.*?◎主  演(?P<main>.*?)<br />◎简  介.*?<td style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<download>.*?)">', re.S)

# 获取主页面内容
def get_main_page():
    main_page = urlopen(main_url).read().decode("gbk")
    # 主页面
    it = reg.finditer(main_page)
    lst = []
    for el in it:
        d = get_son_page(main_url+el.group("url"))
        lst.append(d)
    # indent 控制格式
    json.dump(lst, open("movie.json", mode="w", encoding="utf-8"), indent=4, ensure_ascii=False)

# 获取子页面内容
def get_son_page(son_url):
    content = urlopen(son_url).read().decode("gbk")
    it = son_reg.finditer(content)
    for el in it:
        return {"name":el.group("name").strip(), "main":el.group("main").strip().replace("      ", "").split("<br />"), "download":el.group("download").strip()}

get_main_page()

  

 

posted @ 2019-02-24 14:54  等待の喵  阅读(368)  评论(0编辑  收藏  举报