正则进阶篇

有是一个安静的下午:

 

正则表达式

正则指引:python 语言使用正则表达式

 

能够多去思考 多找答案 从答案中找寻规律 得到属于你自己的感悟

 

 

知识点回顾

 

元字符:\d \w \s \n \t \b \W \D \S\ . ^ $ [] [^] () |

放在字符组中的元字符会现原形()  [不能成对出现] . | + * -

号在中货号中有特殊的意义,需要转义  转义 \加需要转义的内容

 

量词 : 一共六个 + 表示1,+00  *表示 0,+00 ? 表示0|1

{n} 表示n次 {n,} 表示至少n次 {n,m}表示出现n-m次

 

贪婪匹配/惰性匹配:

默认是贪婪匹配 : 回溯 算法

改成惰性匹配 : 量词?

在范围内 尽量少的匹配

?(0.1) 尽量少的匹配就是匹配0次

 

转义符 :

在正则中有特殊意义的字符想让他们表示它本来的意义,就在这个字符前面

加上\

在正则中一些没有特殊意义的字符加上\ 就变成了有特殊意义的字符

 

简单小练习

1,匹配整数或者小数(包括正数和负数)

-?\d+(\.+)?

 

2、匹配年月日日期 格式2018-12-6

^[1-9]\d{3}-(1[0-2)|0?][1-9])-(3[01]|[12]\d])|0?[1-9]

 

  1. 匹配qq号

[1-9]\d{4,11}

 

4 . 十一位的电话号码

[1] [3-9]\d{9}

 

5.长度为8-10位的用户密码

\w{8,10}

 

  1. 匹配验证码 由四位数字字母组成

[0-9a-zA-Z]{4}

 

7匹配邮箱地址

^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$

 

8从类似的

<a>wahaha</a>

 <b>banana</b>

 <h1>qqxing</h1>

 这样的字符串中,

 1)匹配出wahaha,banana,qqxing内容。

     有些时候你要匹配的内容和你不想匹配的内容符合的正则规则是一样的

\w{6}

 >\w+<

 

 2)匹配出a,b,h1这样的内容

 <\w+>

 

 

 9、1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))

 1)从上面算式中匹配出内层没有其他小括号的表达式

 \([^()]+\)

 

 10、从类似9-1000/3+7/3*99/4*2998+10*568/14的表达式中匹配出从左到右第一个乘法或除法

 \d+[*/]\d+

 

 

 

知识点 扩增

Re 模块

基础方法

python中使用正则表达式的特点和问题

使用正则表达式的技巧

爬虫的例子

 

Random模块

 

Re模块

Import re 调用re模块

永远不要起一个py文件 的名字 和已经知道的模块同名

Regex 正则表达式

 

查找

Findall: 匹配所有 每一项都是列表中的每一个元素

import re
ret=re.findall("\d+","打打3213硕大的撒3231")
print(ret)

 

正则表达式,待匹配的字符串,flag

结果是这个

['3213', '3231']

 

Search : 只匹配从左到右的第一个,得到的不是直接的结果,

而是一个变量,通过这个变量的group方法来获取结果

如果没有匹配到,会返回none,使用group会报错

Print(ret)这个一个内存地址 通过 ret.group来获取真正的结果

ret=re.search("\d+","你看到我145的小熊122了么")
print(ret.group())

145

If ret:

Print(ret.group())

 

ret=re.match("\d+","44")
if ret:
    print(ret.group())

 

Match 从头开始匹配,相当于search中的正则表达式加上一个^

^

 

字符串处理的扩展: 替换 切割

Split

s="alex|taibai|jinxing"
print(s.split("|"))
s1='alex83taibai40egon25a'
print(re.split("\d+",s1))

 

 

Sub 谁 旧的 新的 替换次数

ret=re.sub("\d+","H","nisdaldajsdka213213123131")
print(ret)

nisdaldajsdkaH

 

Subn 返回一个元祖,第二个元素是替换的次数

Ret=re.sunb 返回的数字 是在这个程序里 替换的次数

并不是说你标记几次就是几次是  他在可用的时候一红进行替换的次数

就是真实值,比如说你让他替换四次  字符串中只有三个可用替换的

那么他返回的就是3

 

 

Re模块的进阶 :  是时间\空间复杂度

Compile 节省你使用正则表达式解决问题的时间

编译 正则表达式 编译成 字节码

在多次使用的过程中 不会多次编译

一次就解决问题  会很方便 随调随用

 

ret=re.compile("\d+")
print(ret)
res=ret.findall("asdadsad123asdad3213")
print(res)

 

re.compile('\\d+')

['123', '3213']

 

 

Tinditer 节省你使用正则表达式解决问题的空间,也就是内存

 

 

ret=re.finditer("\d+","sadasda21313213sadada142141")
for i in ret:
    print(i.group())

21313213

142141

 

这返回的是个内存地址  需要进行添加到group的形式才可以看到

 

 

Findall 返回列表 找到所有匹配项

 

Search  匹配  返回一个变量  通过group 去匹配到的第一个值,不匹配就返回None group 所有这个时候需要if 语句

Match 就相当于search 的正则表达式添加了一个^ 精准匹配

 

Split 返回列表 按照正则规则切割,默认匹配到的内容会被删掉

Sub/subn 替换 ,按照正则规则去须按照 要被替换掉的内容,subn返回

元祖,第二个值是替换的次数

 

Compile 便以一个正则表达式,用这个结果去search match findall finditer 节省时间

Finditer 返回一个迭代器,所有的结果都在这个迭代器中,需要通过循环+group的形式取值,能够节省内存

 

 

Inport re

s='<a>wahaha</a>'
ret=re.search("<(\w+)>(\w+)</(\w+)>",s)
print(ret.group(1))
print(ret.group(2))
print(ret.group(3))

a

wahaha

a

 

取消分组优先(?:正则表达式)

R

 

关于分组,

对于正则表达式来说 有些时候我哦们需要进行分组,

来整体约束某一字符出现的次数

(\.[\w]+)?

 

对于python语言来说 分组可以帮助你更好更精准的找到你真正需要的内容

<(\w+)>(\w)</(\w+)>

 

Split

ret=re.split('\d+','alxe32asda414115aaadsa23asdada')
print(ret)
ret1=re.split('(\d+)','alxe32asda414115aaadsa23asdada')
print(ret1)

['alxe', 'asda', 'aaadsa', 'asdada']

['alxe', '32', 'asda', '414115', 'aaadsa', '23', 'asdada']

 

用括号把需要的东西括起来 split 会默认显示被切割掉的东西

 

Python 和正则表达式 之间的特殊约定

 

分组命名(?P<这个组的名字>正则表达式)

import re
s = '<a>wahaha</a>'

ret=re.search('>(?P<cont>\w+)<',s)
print(ret.group(0))
ret2 = re.search('>(?P<con>\w+)<',s)
print(ret2.group("con"))

s='<a>wahaha</a>'
pattern="<(\w+)>(\w+)</(\w+)>"
ret=re.search(pattern,s)
print(ret.group(1)== ret.group(3))

 

 

使用前面的分组 要求使用这个名字的分组和前面同名分组中的内容匹配的必须一致

pattern='<(?P<tab>\w+)>(\w+)</(?P=tab)>'
ret=re.search(pattern,s)
print(ret)

 

 

ret=re.findall(r"\d+\.\d+|\d+","1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")

print(ret)
ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
ret1=re.findall(r"\d+\.\d+|\d+","1-2*(60+(-40.35/5)-(-4*3))")
print(ret1)
ret2=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")

ret2.remove('')
print(ret2)
s = '|1132|56564|'
print(s.split("|"))

 

 

['1', '2', '60', '40.35', '5', '4', '3']

['1', '2', '60', '', '5', '4', '3']

['1', '2', '60', '40', '35', '5', '4', '3']

['1', '2', '60', '40.35', '5', '4', '3']

['1', '2', '60', '5', '4', '3']

['', '1132', '56564', '']

 

 

 

简单爬虫

Import

From

import re

from urllib.request import urlopen

 

def getPage(url):   # 获取网页的字符串

    response = urlopen(url)

    return response.read().decode('utf-8')

 

def parsePage(s):

    ret = com.finditer(s)  # 从s这个网页源码中 找到所有符合com正则表达式规则的内容 并且以迭代器的形式返回

    for i in ret:

        yield {

            "id": i.group("id"),

            "title": i.group("title"),

            "rating_num": i.group("rating_num"),

            "comment_num": i.group("comment_num"),

        }

 

def main(num):  # 0  25 50  # 这个函数执行10次,每次爬取一页的内容

    url = 'https://movie.douban.com/top250?start=%s&filter=' % num

    response_html = getPage(url)   # response_html就是这个url对应的html代码 就是 str

    ret = parsePage(response_html) # ret是一个生成器

    print(ret)

    f = open("move_info7", "a", encoding="utf8")

    for obj in ret:

        print(obj)

        data = str(obj)

        f.write(data + "\n")

    f.close()

 

com = re.compile(

        '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>'

        '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S)

 

count = 0

for i in range(10):

    main(count)

    count += 25

转载于:https://www.cnblogs.com/zzy7372/p/9493554.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值