码迷,mamicode.com
首页 > 编程语言 > 详细

python10-模块2

时间:2018-03-16 15:12:01      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:re模块   lin   子节点   需要   ace   abd   对象   import   不同的   

一、json

  序列化

    把对象(变量)从内存中变成可存储或传输的过程

   

  反序列化

    把变量内容从序列化的对象重新读到内存里

    可以通过eval对数据进行序列化

    dic=‘{"name":"alex"}‘
    f=open("hello","w")
    f.write(dic)

    f_read=open("hello","r")
    data=f_read.read()#是个字符串
    print(type(data))
    data=eval(data) #很多语言都支持,但是有局限性,但是函数、类它存不了
    print(data["name"])

 

  json

    什么是json

    如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字    符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非    常方便。

    注意1:json不能序列化类,不过序列化函数和类没有意义,除非你传过去的那边也有个相同的函数

    

    ###通过json对数据进行序列化###

    import json

    dic = {’name’:"alex"}

    f = open("test","w")
    data = json.dumps(dic)
    f.write(data) ##json.dump(dic,f)把dumps和f.write()合起来,仅限文件操作,所以不推荐用
    f.close()

    json序列化处理的内容:把字符串的的单引号变成双引,并把数据(数字、列表、字典、元组等)变成字符串。上述data就变成了字符串,其他语言能用

    # dic={‘name‘:‘alex‘}  #---->{"name":"alex"}----->‘{"name":"alex"}‘
    # i=8                     #---->‘8‘
    # s=‘hello‘              #---->"hello"------>‘"hello"‘
    # l=[11,22]               #---->"[11,22]"

    ############################

 

    ###通过json对数据进行反序列化###

    import json

    f = open("test","r")
    data = json.loads(f.read()) # data=json.load(f)把open和loads两部合起来
    print(data)
    print(type(data))

    f.close()

    这个例子也说明了,不一定要有dumps才能loads出来。只要它符合json规范,就可以被解释、被loads

    #############################

 

二、pickle

    跟json的作用一样,但是它只能用于Python内部的数据交换,不能跨语言,也只有dumps(dumps)和loads(load)两个方法

    

    ###通过pickle对数据进行序列化###

    import pickle

    dic = {‘name‘: ‘alvin‘, ‘age‘: 23, ‘sex‘: ‘male‘}

    f = open("ptest","wb")
    data = pickle.dumps(dic) #会变成字节类型,所以要用wb模式
    print(type(data))
    f.write(data)
    f.close()

    ##############################

 

    ###通过pickle对数据进行反序列化###  

    import pickle
    f = open("ptest","rb")
    data = pickle.loads(f.read()) #会变成字节类型,所以要用wb模式
    print(data["name"])
    print(type(data))
    f.close()

 

三、XML

    实现不同语言或程序之间进行数据交换的协议,作用跟json类似,但是比json复杂。所有的数据都通过标签的实现,文档树结构。Java必学,金融领域不可    缺少。

 

    XML文件结构,如下面的例子:

    <data>
        <country name="Liechtenstein">
            <rank updated="yes">2</rank>
            <year updated="yes">2010</year>
            <gdppc>141100</gdppc>
            <neighbor direction="E" name="Austria" />
            <neighbor direction="W" name="Switzerland" />
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year updated="yes">2013</year>
            <gdppc>59900</gdppc>
            <neighbor direction="N" name="Malaysia" />
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year updated="yes">2013</year>
            <gdppc>13600</gdppc>
            <neighbor direction="W" name="Costa Rica" />
            <neighbor direction="E" name="Colombia" />
        </country>
    </data>

 

    ###xml模块###

    import xml.etree.ElementTree as ET

    tree = ET.parse("xml_lesson") #拿到整个树结构
    root = tree.getroot() #拿到根节点
    print(root.tag)#打印根节点的标签data

 

    ###遍历XML###
    import xml.etree.ElementTree as ET

    tree = ET.parse("xml_lesson") #拿到整个树结构
    root = tree.getroot()  #拿到根节点

    for child in root:  #拿到根节点下的次节点
        print(child.tag, child.attrib)  #次节点的标签和属性
        for i in child:  #拿到次节点下的子节点
            print(i.tag, i.text)  #子节点的标签和文本内容

 

    ###只遍历year节点###
    for node in root.iter(‘year‘): #如果你在country里拿,那就只能取到一个,所以要在根节点用iter方法
        print(node.tag, node.text)

 

    ###修改###

    for node in root.iter(‘year‘):
        new_year = int(node.text) + 1 #修改年份
        node.text = str(new_year) #必须转换成字符串
        node.set("updated", "yes") #新增一个属性

    tree.write("xml_lesson") #文件名不一样就另存为一个文件

 

    ###删除节点###

    for country in root.findall(‘country‘): #这样就不用再用for循环遍历下一个country,findall是找多个
        rank = int(country.find(‘rank‘).text)
        if rank > 50:
            root.remove(country)

    tree.write(‘output.xml‘)

 

    ###生成一个XML###

    import xml.etree.ElementTree as ET

    new_xml = ET.Element("namelist") #创建一个根节点,即<namelist>...</namelist>

    name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})#插入name标签,添加一个属性
    age = ET.SubElement(name, "age", attrib={"checked": "no"})
    sex = ET.SubElement(name, "sex")
    sex.text = ‘33‘
    name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
    age = ET.SubElement(name2, "age")
    age.text = ‘19‘

    et = ET.ElementTree(new_xml)  # 生成文档对象
    et.write("test.xml", encoding="utf-8", xml_declaration=True)

    ET.dump(new_xml)  # 打印生成的格式

 

四、re模块

    正则表达式(或 RE)是一种小型的、高度专业化的编程语言,它内嵌在Python中,并通过re模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配    引擎执行

    正则主要是用于解决模糊匹配,一个现实生活的例子:从身份证号码找出“1970出生的广东省人”
    372324199206034957 男     山东省***     
    623021198705154958 男     甘肃省***     
    429004194306184959 男     湖北省     
    530111197101224956 男     云南省昆明市***     
    440582199706174955 男     广东省***     
    210711198901144954 男     辽宁省锦州市***     
    450521198612214953 男     广西***     
    321119195110314952 男     江苏省***

 

    字符匹配(普通字符和元字符)

    1.普通字符:大多数字符和字母都会和自身匹配

      >>> re.findall("ljy","dsafjaljydfjeiw")
        [‘ljy‘]

    2.元字符:. ^ $ * + ? { } [ ] | ( ) \

      元字符之. ^ $ * + ? { }

      >>> a = re.findall("l..y","dfjljuyaiq") #点是通配符,每一个点代表一个字符,除了\n以外的字符都能匹配
      >>> print(a)
        [‘ljuy‘]

      >>> b = re.findall("^l..y","dfjljuyailabyq") # ^表示以字符串什么为开头,必须是整个字符串的开头才能匹配出来,就是说l一定要出现在字符串的第一位
      >>> print(b)
        []
      >>> b = re.findall("^l..y","ljuyailabyq")
      >>> print(b)
        [‘ljuy‘]

      >>> ret = re.findall("a...j$","dsfkjsdakfyj") # $表示字符串以什么结尾,所以,j一定要出现在字符串的最后一位
      >>> print(ret)
        [‘akfyj‘]

      >>> ret = re.findall("a...j$","dsfkjsdakfyj$")
      >>> print(ret)
        []

      >>> ret = re.findall("abc*","dsfkjabccccsdafyj") # *表示[0,+oo](贪婪匹配),abc*匹配规则中,c字符可以出现0次或者1次或者无限次,但是它只给你返回最高次数
      >>> print(ret)
        [‘abcccc‘]

      >>> ret = re.findall("abc+","dsfkjabccccsdafyj") # +表示[1,+oo](贪婪匹配),abc*匹配规则中,c字符可以出现1次或者2次或者无限次,但是它只给你返回最高次数
      >>> print(ret)
        [‘abcccc‘]
      >>> ret = re.findall("abc+","dsfkjabsdafyj") #但是c字符不能出现0次
      >>> print(ret)
        []

      >>> ret = re.findall("abc?","dsfkjabccccsdafyj") # ? 表示[0,1](贪婪匹配),abc*匹配规则中,c字符可以出现0次或者1次,但是它只给你返回最高次数
      >>> print(ret)
        [‘abc‘]

      >>> ret = re.findall("abc{1,3}","dsfkjabccccsdafyj") # {n,m}表示前面的字符出现n次到m次(贪婪匹配),abc{1,3}匹配规则中,c字符可以出现1次到3次,但是它只给你返        回最高次数
      >>> print(ret)
        [‘abccc‘]

      >>> ret = re.findall("abc{2}","dsfkjabccccsdafyj")
      >>> print(ret)
        [‘abcc‘]

      注意:前面的*,+,?,{}等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配

      >>> ret = re.findall("abc*?","dsfkjabccccsdafyj")
      >>> print(ret)
        [‘ab‘]


      元字符之字符集[ ]:

      >>> ret = re.findall("a[bc]d","dsfkjacdsdafyj") #[bc]表示匹配到b或者c或者bc
      >>> print(ret)
        [‘acd‘]

      >>> ret = re.findall("[a-z]","dsfkjacdsdafyj") #匹配所有小写字母
      >>> print(ret)
        [‘d‘, ‘s‘, ‘f‘, ‘k‘, ‘j‘, ‘a‘, ‘c‘, ‘d‘, ‘s‘, ‘d‘, ‘a‘, ‘f‘, ‘y‘, ‘j‘]
          

      >>> ret = re.findall("[.*+]","a.*+") # . * +这三个元字符放到[]括号里面就失去功能,只是普通的字符
      >>> print(ret)
        [‘.‘, ‘*‘, ‘+‘]

      在字符集里面有功能的符号:\ ^ -

      >>> ret = re.findall("[0-9]","45bdha8") #匹配0到9之间的数字
      >>> print(ret)
        [‘4‘, ‘5‘, ‘8‘]

 

      >>> ret = re.findall("\d","45bdha8") # 匹配十进制数字
      >>> print(ret)
        [‘4‘, ‘5‘, ‘8‘]

      >>> ret = re.findall("[^a]","45bdha8") #[^a]表示取反,不匹配a
      >>> print(ret)
        [‘4‘, ‘5‘, ‘b‘, ‘d‘, ‘h‘, ‘8‘]
      >>> ret = re.findall("[^abcde]","4e5bddhca8") # 不匹配a、b、c、d、e这五个字符
      >>> print(ret)
        [‘4‘, ‘5‘, ‘h‘, ‘8‘]

 

      元字符之转义符\

      反斜杠后面跟元字符:去除特殊功能,如\.

      反斜杠后面跟普通字符:实现特殊功能

      

      \d  匹配任何十进制数;它相当于类 [0-9]。
      \D 匹配任何非数字字符;它相当于类 [^0-9]。
      s  匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。
      \S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。
      \w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
      \W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
      \b  匹配一个特殊字符边界,比如空格 ,&,#等

      

      >>> ret = re.findall("I\b","I AM NOONE")
      >>> print(ret)
        []

      >>> ret = re.findall("I\\b","I AM NOONE")
      >>> print(ret)

        [‘I‘]

      >>> ret = re.findall(r"I\b","I AM NOONE")
      >>> print(ret)
        [‘I‘]

      疑惑:\b在正则中本来就有特殊意义,为何还要加r或者再加一个\?


      因为上面的语句是在python解释器执行的。在re中,它用自己的语言,用\b是可以直接匹配出来的。但现在的执行过程是:Python解释器
      先执行一遍,即读到\b时,python解释器会把它翻译成对应的内容。当python把翻译后的内容交给re时,已经不是re认识的\b。
      r就是raw,规则前面加上r就是告诉python解释器不要进行任何翻译,把\b以生肉的形式交给re。
      至于在\b前面加\的原因,是为了取消后面的\的特殊意义,让它变成一个普通的\,python就不会对它进行翻译,所以普通的\和b就传进去给re,而re认识\b,所以能匹配      成功。


      >>> re.findall("c\\l","abc\lerwt")
        []
      >>> re.findall("c\\\\l","abc\lerwt")
        [‘c\\l‘]

 

      

      re层:为了匹配"c\l",用的是"c\\l",把\转义一下,也就是需要python解释器把"c\\l"传进来
      python解释器层:为了把"c\\l"传给re,python需要对每个斜杠进行转义,所以就是"c\\\\l"
      为什么返回的是"c\\l",因为python的"c\\\\l"传进re就成了"c\\l",而re里面"c\\l"的结果就是"c\l",所以匹配到就返回"c\\l"给python
      python------->re------->"对象"
      "c\\\\l"    "c\\l"      "c\l"
      python<-------re<-------"对象"

 

      元字符之分组()

      >>> re.findall("(ab)","abdafb")
        [‘ab‘]
      >>> re.findall("(ab)+","abdabfb")
        [‘ab‘, ‘ab‘]

      以标签名分组

      >>> res = re.search(‘(?P<id>\d{2})/(?P<name>\w{3})‘,‘23/com‘)
      >>> print(res)
        <_sre.SRE_Match object at 0x7f79a06b4030>
      >>> res.group()
        ‘23/com‘
      >>> res.group(‘id‘)
        ‘23‘
      >>> res.group(‘name‘)
        ‘com‘

      元字符之|

      >>> res = re.findall(‘(rab)|8‘,‘rabhdg8sd‘)
      >>> print(res)
        [‘rab‘, ‘‘]
      >>> res = re.search(‘(rab)|8‘,‘rabhdg8sd‘)
      >>> res.group()
        ‘rab‘
      #()好像就是惰性匹配,匹配到一个就返回,不再进行匹配

    

    3.re模块的常用方法

      >>> re.findall(‘a‘,"alvin yuan")
        [‘a‘, ‘a‘] #返回所有满足匹配条件的结果,放在列表里

      >>> re.search(‘a‘,"alvin yuan").group()
        ‘a‘ #只会找第一个,最短寻找,re.search().group()打印匹配结果,在写计算器的时候很有用

      >>> re.match(‘a‘,"lavin yuan")
      >>> re.match(‘a‘,"alvin yuan")
        <_sre.SRE_Match object at 0x7f79a6dc1f38>
      >>> re.match(‘a‘,"alvin yuan").group() #
        ‘a‘ #当于在search的基础上加了一个^,就是第一个字符必须匹配上

      re.split()以什么进行分割 re.split("[ab]","asdabcd")
      >>> re.split("[ab]","asdabcd")
        [‘‘, ‘sd‘, ‘‘, ‘cd‘]

      过程分析
      先按a分割,左边是空,右边是sdabcd,得到["",sdabcd]
      因为还有a所以再按a分割,得到["","sd","bcd"]
      没有a就按b分割bcd,左边是空,右边是cd,得到["","sd","","cd"]

     

      re.sub("匹配规则","new","old")
      >>> ret = re.sub("\d","abc","alvin5yuan6")
      >>> print(ret)
        alvinabcyuanabc
      >>> ret = re.sub("\d","abc","alvin5yuan6",1) #最后一位限制替换的个数
      >>> print(ret)
        alvinabcyuan6

      re.subn("匹配规则","new","old")返回一个元组,包括了替换后的结果和替换的次数
      >>> ret = re.subn("\d","abc","alvin5yuan6")
      >>> print(ret)
        (‘alvinabcyuanabc‘, 2)

 

      >>> rul = re.compile("\d+") #将写好的规则赋给一个变量
      >>> rul.findall("324dafkjadsnf324jff")
        [‘324‘, ‘324‘]

      与re.findall("\d+","324dafkjadsnf324jff")没有区别,除非在多次调用时,后者需要多次编译,但是
      前者不用。

      

      a = re.finditer(‘\d‘,‘ds3sy4784a‘)迭代匹配,数据很大的时候用。next(a).group()取出结果
      >>> a = re.finditer("\d","ds3sy4784a")
      >>> print(a)
      >>> next(a).group()
        ‘4‘
      >>> next(a).group()
        ‘7‘
      >>> next(a).group()
        ‘8‘
      >>> next(a).group()
        ‘4‘
      >>> next(a).group()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      StopIteration

    

      findall需要注意的一点:

      >>> res = re.findall("www.(baidu|163).com","www.baidu.com")
      >>> print(res)
        [‘baidu‘]

      我们期望的结果的是“www.baidu.com”,但是findall跟组“()”结合的话,会优先把组里面的匹配结果返回,可以通过取消权限去避免

      >>> res = re.findall("www.(?:baidu|163).com","www.baidu.com")
      >>> print(res)
        [‘www.baidu.com‘]

python10-模块2

标签:re模块   lin   子节点   需要   ace   abd   对象   import   不同的   

原文地址:https://www.cnblogs.com/liangjiongyao/p/8570457.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!