Day 15 正则表达式 re模块

1.正则表达式

  1.正则表达式不是Python独有的,它是一门独立的技术,如果在python中使用,必须导入re模块,正则表达式用来筛选字符串中的特定内容,一般情况下遇到reg都是与正则有关系

  2.如果匹配具体内容,可以直接西,不需要正则表达式

  3.正则表达式一般由元字符与量词组成

  4.元字符

元字符 匹配内容与注意事项
\d digit   匹配所有数字         注[\d\D],[\W\w],[\s\S] 任意一组可以匹配任意字符
\w word  匹配字母数字下划线
\s space  匹配所有空格(包括空格,制表符回车)
\D   匹配非数字的所有字符
\W   匹配所有非字母数字下划线的所有字符  
\S   匹配所有非空格的所有字符
\n   匹配回车符
\t   匹配制表符
\b   匹配一个单词的结尾
.   匹配除换行符以外的所有字符
^   匹配字符串的开始                                       ^与$合用会精准的限制匹配内容,中间写什么就只匹配什么
$   匹配字符串的结尾
|   或  注:只会匹配或符号两边的其中一个,从左往右,  所以要把长的放在短的前面
[..]   匹配字符组的字符 用[]来限定,一个字符组只针对一个字符,字符组里面的内容都是或的关系  可以[1-9] 但要注意里面数字必须是从小到大
()   匹配括号内的表达式,表示一个组
[^...]   匹配非字符组里字符的内容   ^在字符组里是取反的意思

  5:量词. 必须跟在正则符号也就时元字符后面,并且量词只能限制它前面紧挨着他的表达式

量词 使用说明
*  匹配0次或无穷大次
+ 匹配1次或无穷大次
? 匹配0次或1次
{n} 指定匹配重复n次
{m,n} 指定匹配重复 m-n 次
{m,} 指定匹配重复m次到无穷大次

  6.转义字符   当我们需要匹配的内容中就是需要匹配\n而不是匹配换行符时就需要对\n中的\转义 如"\\n"  "\."(匹配.本身) 用\转义

  7.贪婪匹配:  在满足匹配时,匹配尽可能长的字符串   

  8.惰性匹配:  在正则表达式量词后面加?  如 .*?    .+?  {m,n}?   {n,}?

  9.   .*? 的用法    .*?x   意思就是取前面任意长度的字符直到遇到X停止

2.re模块: python中使用正则必须使用re模块

  1. re.findall  语法 re.findall('正则表达式', '待匹配的字符串')

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.findall('\d',s)  # 找出字符串中正则表达式全部内容,返回一个列表,列表中元素就时正则匹配到的结果
print(res)  # ['1', '4', '1', '4', '5', '3', '5']

  2. re.search  语法: re.search('正则表达式', '待匹配的字符串')

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.search('\d',s)  # 只会依据正则查一次 只要查到了结果 就不会再往后查找
print(res)  # 不会直接返回匹配到的结果,而返回一个对象   没匹配到返回None
print(res.group())   # 1   必须用group 才能看到匹配到的结果  如果没匹配到会报错

  3. re.match    语法: re.match('正则表达式', '待匹配的字符串')

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.match('\d',s)  # 只会匹配字符串开头部分
print(res)  # 不会直接返回匹配到的结果,而返回一个对象   没匹配到返回None
print(res.group())   # 1   必须用group 才能看到匹配到的结果  如果没匹配到会报错

  4. group   当使用re.search与re.match 时会返回一个对象.需要用group取值

  5. re.split  语法: re.split('正则表达式', '待匹配的字符串',切割次数)

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.split('\d',s)  # 以匹配到的结果对字符串进行分割 返回一个列表
print(res)  # ['', 'hkj', 'h', '', 'v', 'gh', '', 'mbjkkjk']

  6 .re.sub  语法: re.sub('正则表达式','新的内容' ,'待匹配的字符串',替换次数)

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.sub('\d','哈哈',s)  # 将s中每一个能被匹配到的替换成哈哈  
print(res)  # 哈哈hkj哈哈h哈哈哈哈v哈哈gh哈哈哈哈mbjkkjk

  7. re.subn 语法: re.subn('正则表达式','新的内容' ,'待匹配的字符串',替换次数)

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.subn('\d','哈哈',s)  # 将s中每一个能被匹配到的替换成哈哈,返回一个元组,第二个元素是共替换的次数
print(res)  # ('哈哈hkj哈哈h哈哈哈哈v哈哈gh哈哈哈哈mbjkkjk', 7) 

  8. re.compile  语法: re.compile('正则表达式')   将传入的正则表达式一次性编译,可以拿到任意地方运行.节省时间,提高开发效率

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.compile('[0-9]')  
print(re.findall(res,s))  # ['1', '4', '1', '4', '5', '3', '5']

  9. re.finditer  语法: re.finditer('正则表达式', '待匹配的字符串')  返回一个存放匹配结果的迭代器  节省内存空间

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.compile('[0-9]')
res1 = re.finditer(res,s)
print(next(res1).group())   # 通过next得到一个对象,用group取值
print(next(res1).group())
print(next(res1).group())
print(next(res1).group())
print(next(res1).group())
print(next(res1).group())
print(next(res1).group())  # 当值取完继续去触发StopIteration异常

  10 re模块中分组的使用:

    (1)  按分组取

import re
res = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','130120122232422159')
print(res.group())
print(res.group(0))  # 与group 等价
print(res.group(1))  # 第一个分组匹配到的内容
print(res.group(2))  # 第二哥分组匹配到的内容

    (2) 起别名  在分组内使用 ?P<名字> 起别名,注意P大写,  注意用别名访问时别名需要加引号

import re
res = re.search('^[1-9](?P<name>\d{14})(?P<pwd>\d{2}[0-9x])?$','130120122232422159')
print(res.group())
print(res.group(0))  # 与group 等价
print(res.group(1))  # 第一个分组匹配到的内容
print(res.group(2))  # 第二哥分组匹配到的内容
print(res.group('name'))  # name 匹配的内容
print(res.group('pwd'))  # pwd 匹配的内容

    (3)  使用re.findall 分组存在时,分组优先      在分组内使用?:  取消优先

import re
ret1 = re.findall('www.(baidu|163).com', 'www.163.com')  # 分组优先
print(ret1)   # ['163']
ret2 = re.findall('www.(?:baidu|163).com', 'www.163.com')  # 分组内使用?:取消分组优先
print(ret2)  # ['www.163.com']

    (4) 使用re.split 分组存在时不会将 匹配到内容丢掉

import re
s = '1hkj4h14v5gh35mbjkkjk'
res = re.split('(\d)',s) 
print(res)  # ['', '1', 'hkj', '4', 'h', '1', '', '4', 'v', '5', 'gh', '3', '', '5', 'mbjkkjk']

3 爬虫案例.

import requests

import re
import json


def getPage(url):
    response = requests.get(url)
    return response.text


def parsePage(s):
    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)

    ret = com.finditer(s)
    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):
    url = 'https://movie.douban.com/top250?start=%s&filter=' % num
    response_html = getPage(url)
    ret = parsePage(response_html)

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

    for obj in ret:
        print(obj)
        data = json.dumps(obj, ensure_ascii=False)
        f.write(data + "\n")


if __name__ == '__main__':
    count = 0
    for i in range(10):
        main(count)
        count += 25

 

posted @ 2019-07-17 16:48  人生能有几回搏  阅读(188)  评论(0编辑  收藏  举报