正则表达式

分类

  结构化数据

    定义:数据以为单位,每一个数据表示一个实体信息,每一行数据的属性都是一样的

    例如:结构化数据为关系型数据存储数据

  半结构化数据

    定义:结构化数据的另一种形式,但是并不符合关系型数据的特点,不能用关系模型来描述,但这种数据包含相关标记,例如:xml,html,json。

  非结构化数据

    定义:没有固定的结构  

    常见的非结构化数据有:文档,图片,音频,视频等。

    一般非结构化数据都是通过整体存储他们二进制格式的数据来进行保存。

Json数据

  js语言的,在js语言中,json是用来以字符串的形式来保存js中的对象和数组一种技术。

  json本质上就是一个字符串,但这个字符串有特殊含义:保存的是js中的对象和数组

  js中对象和数组的格式

    js数组: var names=["zhangsan","ls","ww","aa","bbb"]---->和python的列表很像

    js的对象:var zhangsan = {name:'zhangsan',age:18'

  json数据在python中可以json这个模块来进行解析。
    var names-->数组--->json数据:var name_json = '["zhangsan","ls","ww","aa","bbb"]'--->变成字符串之后有什么优势呢?--->可以在网络上传输了。
    json模块有四个方法:
      json.loads(json_str)--->json_data:python的list或者dict
      json.dumps(json_data)--->json_str
  json的意义.
    json作为数据格式传输时,具有较高的效率,这是因为json不像xml那样具有严格的闭合标签,这就让有效数据与总数据包的比,也就是数据的有效占比大大提高。               从而减少了同等数据流量下的json数据传输内容更多,大大减轻了网络传输的压力。

正则表达式
1、元字符
  (1)匹配边界
    ^----行首
    $----行尾
  (2)重复次数
    ?----重复0或1
    *----》0
    +----》1
    {n,}----》n
    {n,m}---->=n,<=m
    {n}----重复n次
  (3)各种字符表示
    []----匹配括号中的其中一个字符,也就会匹配但单一字符。
    [abc]----匹配a或者b或者c的其中一个
    [a-z]----匹配a-z的其中任意一个
    [0-9]----匹配0-9的其中任意一个
    \d-----数字
    \w-----数字、字符、下划线
    \s-----空白字符:空格,制表,换行
    \b-----单词的边界
    .------除换行符以外的任意字符。
2、正则表达式在python就是通过re模块来进行处理的。
  re模块的使用步骤:
  (1)pattern = re.compile('正则表达式'),将正则表达式编译为一个pattern对象。
  (2)pattern对象有一系列筛选方法,比如match,search等,调用这些方法对文本进行筛选。返回一个match对象
  (3)拿到match对象,获取数据。

3、pattern对象的筛选方法:
  (1)match方法:默认从头开始匹配,只匹配一次,返回一个match对象。

 pattern.match(
  '需要匹配的字符串',
  start,匹配的开始位置
  end,匹配的结束位置。
  )---->match对象。
  match对象的方法:
  match.group()---取匹配内容
  match.span()---取匹配范围
  match.start()---取匹配开始位置
  match.end()---取匹配结束位置
  这几个方法都可以传0这个参数,表示匹配内容的东西,如果传>0,1,2,等这些数字,就是取分组内容。

 

(2)search方法:从任意位置匹配,只匹配一次,返回一个match对象。
  

pattern.search(
  '需要匹配的字符串',
  start,匹配的开始位置
  end,匹配的结束位置。
  )---->match对象。

(3)findall方法:全文匹配,匹配多次,将每次匹配到的结果放到一个list中返回
  

pattern.findall(
  '需要匹配的字符串',
  start,匹配的开始位置
  end,匹配的结束位置。
  )---->list.

(4)finditer方法:全文匹配,匹配多次,返回一个迭代器。
  

pattern.findall(
  '需要匹配的字符串',
  start,匹配的开始位置
  end,匹配的结束位置。
  )---->返回一个迭代器。

 


(5)split:按照正则所能匹配的内容进行字符串的切分。

pattern.split(
'需要匹配的字符串',
切分的次数。不指定的时候全部切分。
)---->返回一个切分后的list。

(6)sub:用指定字符串,替换正则表达式在原字符串所能匹配到的内容。

pattern.split(
repl,替换成什么,
content,替换什么,
count,可以不指定,默认是替换所有,指定就是替换几次。
)---->返回替换后的字符串


repl可以是字符串,此时就表示用字符串替换。也可以是函数,此时这个函数是有格式要求的。
函数的要求:
1、函数必须带一个参数,这个参数是用正则匹配content所能匹配的到的macth对象。
2、这个函数必须有返回值,返回值必须是一个字符串,将来就用这个字符串作为替换对象。

def func(m):
return str_
p.sun(func,content)--->p.sub(str_,cotent)
比如:
#让张三涨2000
p = re.compile(r'(\d+)')
res = p.sub('5000',content,1)
print(res)

# 所有人都涨1000

def add(m):
return str(int(m.group())+1000)
res = p.sub(add,content)
print(res)

4、分组:分组在正则表达式中就是用()来表示的。一个括号就是一个分组。
分组的作用:
  (1)筛选特点内容
    通过给特点的内容加一个(),将来可以通过group(1)方式取到这个括号内的东西。

1 import re
2 
3 content = '{name:"zhangsan",age:"10",hobby:["basktball","football","read"]}'
4 pattern = re.compile(r'{name:"(\w+)",age:"(\d+)".+')
5 match = pattern.search(content)
6 print(match.group(0))
7 print(match.group(1))#zhangsan
8 print(match.group(2))#10

(2)可以在同一个表达式中引用前面的分组表达式。

import re

s = "<html><h1>正则表达式</h1></html>"
pattern = re.compile(r'<(html)><(h1)>(.*)</\2></\1>')
match = pattern.search(s)
print(match.group(3))

5、贪婪匹配和非贪婪匹配
  (1)贪婪和非贪婪的区分在于匹配内容的多少。
  (2)贪婪是用*来控制的。
  (3)非贪婪是用?来控制的。
  (4)正则默认情况下是贪婪模式来匹配的,所以数量控制符,
    +----》1 -----[1:]----取能够匹配到的最大值。
    {n,}----》n
    {n,m}---->=n,<=m
    {n}----重复n次
    都是取得最大值。
(5)在表示重复字数的元字符后面加一个?,此时这个表示重复次数的元字符就只能取最小值。
    +?--- +【1:】---》+?:1

 

正则表达式爬取数据(股吧):

import json

import requests,re

infos = []
def parse_page(html_str):
    ul_p = re.compile(r'<ul class="newlist" tracker-eventcode="gb_xgbsy_ lbqy_rmlbdj">(.*?)</ul>',re.S)
    ul_content = ul_p.search(html_str).group(1)
    # print(ul_content)
    ##用正则匹配原则:不断搜小匹配范围,最后做到精确匹配。
    li_p = re.compile(r'<li>(.*?)</li>',re.S)
    li_list = li_p.findall(ul_content)
    # print(li_list)
    for li in li_list:
        infos_p = re.compile(r'<cite>(.*?)</cite>',re.S)
        infos = infos_p.findall(li)
        read_num = infos[0].strip()
        comment_num = infos[1].strip()
        # print(read_num,comment_num)
        title_p = re.compile(r'title="(.*?)" class="',re.S)
        title = title_p.search(li).group(1)
        # print(title)
        #作者
        author_p = re.compile(r'<font>(.*?)</font>', re.S)
        author = author_p.search(li).group(1)
        #发表日期
        date_p = re.compile(r'<cite class="date">(.*?)</cite>', re.S)
        date = date_p.search(li).group(1)
        #更新时间
        refresh_date_p = re.compile(r'<cite class="last">(.*?)</cite>', re.S)
        refresh_date = refresh_date_p.search(li).group(1)
        detail_p = re.compile(r' <a href="(.*?)" title="', re.S)
        detail = detail_p.search(li).group(1)
        item = {}
        item['read_num'] = title
        item['comment_num'] = title
        item['title'] = title
        item['author'] = author
        # print(author)
        item['date'] = date
        item['refresh_date'] = refresh_date
        item['detail'] = detail
        # print(detail)
        # print(item)
        #将数据保存到json文件
        infos.append(item)
def write_to_file(file,infos):
    with open(file,'w',encoding='utf-8') as fp:
        json.dump(infos,fp)
def main():
    base_url = 'http://guba.eastmoney.com/default,99_%s.html'
    headers= {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
    }
    for i in range(1,2):
        response = requests.get(base_url %i,headers = headers)
        # print(response.text)
        parse_page(response.text)
    write_to_file('guba.json',infos)
if __name__ == '__main__':
    main()

 

 

posted @ 2019-12-01 21:41  佑神  阅读(285)  评论(0)    收藏  举报