正则表达式解析

bs4
xpath
三种解析方式

正则表达式解析

为什么引入正则表达式?

  • 用来匹配一类具有相同规则的字符串

    规则:

  • 单字符:

         . :除换行外的所有的字符
         [] :[aoe]表示:a,o,e,任意一个;[a-w]:表示a到w之间任意一个;匹配集合中任意一个字符
         \d :数字  [0-9]:表示0到9
         \D: 非数字
         \w :数字,字母,下划线,中文
         \W :非小w
         \s :所有的空白字符
         \S :非空白
    
  • 数量修饰(控制次数):

         *   :任意多次    >=0
         +   :至少一次   >=1
         ?   :可有可无   0次或者一次
         {m}  :固定m次
         {m,}    :至少m次
         {m,n}   :m-n次
    
  • 边界:

         \b  \B  
         $   :以某某结尾
         ^   :以某某开头
    

分组(正则的高级功能):

        ():视为一个整体
                 ab{4} : 匹配的是abbbb
                (ab){4} :表示()里面的出现4次,abababab
            :子模式\组模式        \1\2
                #需求:匹配出<div><span>猪八戒</span></div>
                import re
                string = "<p><div><span>猪八戒</span></div></p>"
                pattern =re.compile( r"<(\w+)><(\w+)>\w+</\2></\1>")
                ret = pattern.search(string)
                print(ret)
                #结果:<_sre.SRE_Match object; span=(3, 30), match='<div><span>猪八戒</span></div>'>
        贪婪模式:
            .*?      .+?        加?可以取消贪婪
            例子:
            import re
            string = "<div>如来</div></div></div>"
            pattern = re.compile(r"<div>.*</div>")
            ret = pattern.search(string)
            print(ret)
            
            # 结果:<_sre.SRE_Match object; span=(0, 25), match='<div>如来</div></div></div>'>
            # .*都能匹配,匹配到最后
            
            #如果加?
            import re
            
            string = "<div>如来</div></div></div>"
            pattern = re.compile(r"<div>.*?</div>")
            ret = pattern.search(string)
            print(ret)
            
            # 结果:<_sre.SRE_Match object; span=(0, 13), match='<div>如来</div>'>
            #加?号,?号后面的</div>代表正则的结尾
        re.I    :忽略大小写
        re.M    :多行匹配

例子:

import re

string = 三引号hate is a beautiful feel
 love you very much
 love she
 love her三引号
 pattern = re.compile(r"^love",re.M)      #多行匹配以love开头的
 ret = pattern.findall(string)           #findall是匹配所有,search是匹配一个
 print(ret)
 
 #结果:['love', 'love', 'love']        

   
        
        re.S    :单行匹配

#需求:把里面的内容去出来

import re
string1 = """<div>沁园春-雪
北国风光
千里冰封
万里雪飘
望长城内外
惟余莽莽
大河上下
顿失滔滔
山舞银蛇
原驰蜡象
欲与天公试比高
</div>"""
pattern = re.compile(r"<div>(.*)</div>",re.S)      #单行模式,.就可以匹配换行符
ret = pattern.findall(string1)           #findall是匹配所有,search是匹配一个
print(ret)

#结果:['沁园春-雪\n北国风光\n千里冰封\n万里雪飘\n望长城内外\n惟余莽莽\n大河上下\n顿失滔滔\n山舞银蛇\n原驰蜡象\n欲与天公试比高\n']

match:从开头开始找
search:从任一位置开始找
findall:找所有

re.sub(正则表达式,替换内容,字符串) 意思:在字符串中查找到正则匹配的内容,替换为“替换内容”

import re
string = "i love you,you love me, ye"
pattern = re.compile(r"love")
ret = pattern.sub("hate",string)
print(ret)
#结果:i hate you,you hate me, ye

还有一种

import re
string = "i love you,you love me, ye"
ret = re.sub(r"love","hate",string)
print(ret)
#结果:i hate you,you hate me, ye
#正则替换

#需求,在身高的基础上减去10

import re

def fn(a):
    #print(a)           #<_sre.SRE_Match object; span=(6, 9), match='175'>
    ret = int(a.group())  #把175提取出来
    #print(ret)          #175
    return str (ret - 10)

string = "我喜欢身高为175的女生"
pattern = re.compile(r"\d+")
ret = pattern.sub(fn, string)
print(ret)
#结果:我喜欢身高为165的女生

#需求:糗事百科,图片下载

import urllib.request
import urllib.parse
import re
import os
import time


def handle_request(url,page):
    url = url + str(page) + "/"
    #print(url)
    headers = {
         "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
    }
    #根据头和url,就可以构建请求对象
    request = urllib.request.Request(url=url,headers = headers)
    return request


def download_image(content):
    pattern = re.compile(r'<div class="thumb">.*?<img src="(.*?)" .*?>.*?</div>', re.S)  # re.S单行模式
    lt = pattern.findall(content)
    # print(lt)
    # 遍历列表,依次下载图片
    for image_src in lt:
        # 先处理image_src
        image_src = "https:" + image_src
        # 发送请求,下载图片
        # 创建文件夹
        dirname = "qiutu"
        if not os.path.exists(dirname):
            os.mkdir(dirname)
        # 图片的名字是啥
        filename = image_src.split("/")[-1]
        filepath = dirname + "/" + filename
        print("s%图片正在下载......"%filename)
        urllib.request.urlretrieve(image_src, filepath)
        print("s%图片结束下载......" % filename)
        time.sleep(1)




def main():
    url = "https://www.qiushibaike.com/pic/page/"
    start_page = int (input("请输入起始页码:"))
    end_page = int (input("请输入结束页码:"))
    for page in range(start_page, end_page + 1):
        print("第%s页开始下载。。。" % page)
        # 生成请求对象
        request = handle_request(url, page)
        # 发送请求对象,获取响应内容
        content = urllib.request.urlopen(request).read().decode()
        # 解析内容,提取所有的图片链接,下载图片
        download_image(content)
        print("第%s页下载结束。。。" % page)
        print()
        print()
        time.sleep(2)


if __name__ == '__main__':  # 如果设置一个主程序,运行的话,就会执行里面的代码,如果被别的程序调用,就不会执行
    main()
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐