zoukankan      html  css  js  c++  java
  • python进阶(十七)正则&json(上)

    1. 一个列表中所有的数字都是重复2次,但是有一个数字只重复了一次。

    请找出重复一次的数字,不可以使用内置函数。

    [2,2,1,1,0,4,3,4,3]

    方法1:通过字典计数,找到value等于1的key

    s = [2,2,1,1,0,4,3,4,3]

    m = {}

    for i in s:

        if i in m:

            m[i]+=1

        else:

            m[i] = 1

    print(m)

    for k,v in m.items():

        if v ==1:

            print (k)

    #运行结果:

    #{2: 2, 1: 2, 0: 1, 4: 2, 3: 2}

    #0

    方法2:使用排序,判断在头、中、尾三种情况

    s = [2,2,1,1,0,4,3,4,3]

    s = sorted(s)

    for i in range(len(s)):

        if i == 0 and s[1] !=s[0]:

            print(s[0])

            break

        elif i == lens(s)-1 and s[i] s=s[i-1]:

            print(s[i])

        else:

            if i!=len(s)-1 and i!=0 and s[i]!=s[i+1] and s[i]!=s[i-1]:

                print(s[i])

                break

    #运行结果:

    #0

    方法3:使用内置函数append和remove

    s = [2,2,1,1,0,4,3,4,3,0,-1]

    relist = []

    for i in s:

        if i in relist:

            relist.remove(i)

        else:

            relist.append(i)

    print(relist[0])

    #运行结果:

    #-1

    方法4:使用字典,优点:哈希查找,速度快

    s = [2,2,1,1,0,4,3,4,3,0,-1]

    redict = {}

    for i in s:

        try:

            redict[i] +=1

            del redict[i]

        except:

            redict[i] = 1

    print(redict.keys())

    #运行结果:

    #dict_keys([-1])

    print(list(redict.keys()))

    #运行结果:

    #[-1]

    print(list(redict.keys())[0])

    #运行结果:

    #-1

    输出结果时,换个方法:

    print(redict)            #查看redict中的内容

    #{-1: 1}

    print(dir(redict))        #查看字典可用的方法

    #['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

    print(redict.popitem()) #使用pop.item方法,将字典转换为tuple,且在源字典中删除该组

    #(-1, 1)

    print(redict)         #再次查看redict,已经变成空,因为redict中只有一个key和value

    {}

    print(redict.popitem()[0])#所以,要将所有代码写在一起,防止pop后在取值取不到报错

    -1

     

    d = {1:2,3:4}         #有两组key和value的字典

    print(d.popitem())

    #(3, 4)              #popitem出来的是第二组的key和value

    print(d)              

    #{1: 2}              #再次查看原字典,只留下未pop的数据

    print(d.popitem())

    #(1, 2)

    2. 写个程序可以处理下面的情况

    Example 1:

    Input: s = "leetcode", wordDict = ["leet", "code"]

    Output: true

    Explanation: Return true because "leetcode" can be segmented as "leet code".

     

    Example 2:

    Input: s = "applepenapple", wordDict = ["apple", "pen"]

    0utput: true

    Explanation: Return true because " applepenapple" can be segmented as "apple pen apple".

                 Note that you are allowed to reuse a dictionary word.

     

    Example 3:

    Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]

    Output: false

     

     

    方法1:

    import re

    s = "leetcode"

    word_dict = ["leet","code"]

    pattern = re.compile("("+"|".join(word_dict)+")")

    print(pattern)

    #re.compile('(leet|code)')

    result = pattern.findall(s)

    print(result)

    #['leet', 'code']

    print(len("".join(result))==len(s))

    #True

    import re

    s = "leetcodex"

    word_dict = ["leet","code"]

    pattern = re.compile("("+"|".join(word_dict)+")")

    print(pattern)

    #re.compile('(leet|code)')

    result = pattern.findall(s)

    print(result)

    #['leet', 'code']

    print(len("".join(result))==len(s))

    #False

    方法2:

    import re

    s = "leetcode"

    word_dict = ["leet","code"]

    result = s

    for i in word_dict:

        result = "".join(re.split(i,result))

    print(result == "")

    #True

    import re

    s = "leetcodex"

    word_dict = ["leet","code"]

    result = s

    for i in word_dict:

        result = "".join(re.split(i,result))

    print(result == "")

    #False

    一、正则表达式

    1、正则表达式 – 后向引用

    正则表达式中,放在圆括号”()”中的表示是一个分组。然后我们就可以对整个组使用一些正则操作,例如重复操作符。

    要注意的是,只有”()”才能形成分组,””用于定义字符串,而“{}”用于定义重复操作。当用”()”定义了一个正则表达式分组后,正则引擎就会把匹配的组按照顺序进行编号,然后存入缓存中。这样我们就可以在后面对已经匹配过的内容进行引用,这就叫后向引用。

        1. 通过索引引用

    数字

    1表示引用第一个分组,2引用第二个分组,以此类推,而则表示引用整个被匹配的正则表达式本身。

        2. 通过命名分组名进行引用(如果有的话)

    (?P=name)

    字符P必须是大写的P,name表示命名分组的分组名。

    注意:

    这些引用都必须是在正则表达式中才有效,用于匹配一些重复的字符串。

        1) 通过默认分组编号进行后向引用

    import re

    s = "22 22 aa"

    print(re.search(r"(d{2}) 1",s).group())  #1的意思是必须匹配和第一个分组匹配一样的内容

    #22 22                            #后向引用,引用了分组1

    s = "22 aa 22"

    print(re.search(r"(d{2}) 1",s).group())

    #AttributeError: 'NoneType' object has no attribute 'group'

    s = "22 21 22"

    print(re.search(r"(d{2}) 1",s).group()) #虽然21满足d{2},但是21和22的内容不一样,即

    1匹配到的内容和d{2}匹配到的内容不一样,所以未匹配成功

    #AttributeError: 'NoneType' object has no attribute 'group'

    1表示第一个分组匹配到的内容

        2) 通过命名分组进行后向引用

    import re

    res = re.search(r'(?P<name>go)s+(?P=name)s+(?P=name)', 'go go go')

    print(res.group())

    #go go go

    3) 交换字符串的位置

    import re

    s = "abc.xyz"

    res = re.sub(r"(.*).(.*)",r"2.1",s)

    print(res)

    #xyz.abc

    2、正则表达式 – 前向肯定断言与后向肯定断言

    前向肯定断言的语法:

    (?<=pattern)

    前向肯定断言表示你希望匹配的字符串前面是pattern匹配的内容时,才匹配

    后向肯定断言的语法是:

    (?=pattern)

    后向肯定断言表示你希望匹配的字符串是后面是pattern匹配的内容时,才匹配

    import re

    print(re.search(r"(?<=abc)d+","abc123").group())#匹配前面是abc的多个数字

    #123

    print(re.search(r"(?<=abc)d+","a1c123").group())

    #AttributeError: 'NoneType' object has no attribute 'group'

    print(re.search(r"d+(?=abc)","123abc").group()) #匹配后面是abc的多个数字

    #123

    print(re.search(r"d+(?=abc)","123a1c").group())

    #AttributeError: 'NoneType' object has no attribute 'group'

    前向肯定断言括号中的正则表达式必须是能确定长度的正则表达式,比如W{3},而不能写成w*或者w+或者w?等这种不能确定个数的正则模式符。

    import re

    s = "aaa111aaa,bbb222,333ccc"

    print(re.findall(r"(?<=[a-z]{3})d+(?=[a-z]+)",s))   #指定前后肯定断言

    #['111']

    print(re.findall(r"(?<=[a-z]{3})d+",s))          #指定前向肯定断言

    #['111', '222']

    print(re.findall(r"d+(?=[a-z]+)",s))             #指定后向肯定断言

    #['111', '333']

    print(re.findall(r"[a-z]+d+[a-z]+",s))           #普通匹配方法

    #['aaa111aaa']

    try:

        matchResult = re.findall(r"(?<=[a-]+)d+(?=[a-z+])",s)#前向肯定未固定宽度

    except Exception as e:

        print(e)

    else:

        print(matchResult)

    #look-behind requires fixed-width pattern  #前向匹配需要固定宽度的匹配模式

    3、正则表达式 – 前向否定断言与后向否定断言

    前向否定断言的语法:

    (?<!pattern)

    前向否定断言表示你希望匹配的字符串的前面不是pattern匹配的内容时,才匹配。

    后向否定断言的语法:

    后向否定断言表示你希望匹配的字符串的后面不是pattern匹配的内容时,才匹配。

    和前向肯定断言一样,前向否定断言括号中的正则表达式必须是能确定长度的正则表达式,比如W{3},而不能写成w*或者w+或者w?等这种不能确定个数的正则模式符。

    import re

    s = "aaa111aaa,bbb222,333ccc"

    print(re.findall(r"(?<![a-z]{3})d+(?![a-z]+)",s))  #指定前后否定断言

    #['1', '22', '33']

    print(re.findall(r"(?<![a-z]{3})d+",s))         #指定前向否定断言

    #[['11', '22', '333']

    print(re.findall(r"d+(?![a-z]+)",s))           #指定后向否定断言

    #['11', '222', '33']

    print(re.findall(r"[a-z]+d+[a-z]+",s))         #普通匹配方法

    #['aaa111aaa']

    try:

        matchResult = re.findall(r"(?<![a-]+)d+(?![a-z+])",s)#前向否定断言未确定长度

    except Exception as e:

        print(e)

    else:

        print(matchResult)

    #look-behind requires fixed-width pattern

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

    二、JSON

    1、使用Python语言来编码和解码JSON对象

    Python的json模块序列化和反序列化分别是dumps和loads

    json.dumps():将一个Python对象编码成JSON字符串

    json.loads():将JSON格式字符串解码成Python对象

    对简单的数据类型可以直接处理。如:string,Unicode,int,float,list,tuple,dict

    2、JSON简介

    JSON:JavaScript Object Notation(JavaScript对象表示法)

    JSON:是存储和交换文本信息的语法。类似XML(存储数据的格式,有格式的存储数据)

    JSON比XML更小、更快,更易解析。

     3、JSON语法与语法规则

    1) JSON语法:

    JSON语法是JavaScript语法的子集。

    2) JSON语法规则:

    JSON语法是JavaScript对象表示法语法的子集。

    1. 数据在名称/值对中

    2. 数据由逗号分隔

    3. 花括号保存对象

    4. 方括号保存数组

    4、JSON名称/值对

    Json数据的书写格式是

    名称/值对

    名称/值对包括字段名称,后面写一个冒号,然后是值,比如:

    “firstName”:”John”

    等价于下面这条JavaScript语句:

    firstName = “John”

    JSON值可以是:

    数字(整数或浮点数)

    字符串(在双引号中)

    逻辑值(true 或false),区别于Python的True和False

    数组(在方括号中)

    对象(在花括号中)

    null

    5、JSON对象

    JSON对象是在花括号中书写的。对象可以包含多个名称/值对。比如:

    {“firstName”:”John”,”lastName”:”Doe”}

    这等价于JavaScript语句:

    firstName = “John”

    lastName = “Doe”

    6、JSON数组

    JSON数组是在方括号中书写的。数组可以包含多个对象。比如:

    a = {

        "employees":[

            {"firstName":"John","lastName":"Doe"},

            {"firstName":"Anna","lastName":"Smith"},

            {"firstName":"Peter","lastName":"Jones"}

        ]

    }

    print(a)

    在上面的例子中,对象”employees”是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。

     7、JSON解码:

    1)将json格式字符串解码成Python对象,我们使用的是json.loads()函数,可以将

    简单数据类型解码成Python对象。

    json.loads                           #将json串转换为dict类型

    >>> s = '{"name":"hehe","age":"18"}'      #s定义了一个json串

    >>> print(s)

    {"name":"hehe","age":"18"}

    >>> print(type(s))                         #json串的数据类型是str

    <class 'str'>

    >>> import json                           #引入json包

    >>> json.loads(s)                         #json.loads(s)将json串转换为dict类型

    {'name': 'hehe', 'age': '18'}

    >>> print(type(json.loads(s)))              #查看json.loads后的数据类型,是dict

    <class 'dict'>

    >>> s                                   #查看经过json.loads后的s是否有变化

    '{"name":"liuyujing","age":"18"}'             #s没有变化

    >>> s1 = json.loads(s)

    >>> print(type(s1))

    <class 'dict'>

    >>> print(s)                            #s是str类型,但是print(s)是没有””的

    {"name":"liuyujing","age":"18"}

    >>> print(type(s))

    <class 'str'>

    >>> s                                 #交互模式下,直接s会显示’’

    '{"name":"liuyujing","age":"18"}'

     

    >>> data = [{'a':"Aasdf",'b':(2,4),'c':3.0}]    #原始数据中有tuple(2,4)

    >>> json.dumps(data)

    '[{"a": "Aasdf", "b": [2, 4], "c": 3.0}]'        #经过json编码后,变成了JSON的数组

    >>> json.loads(json.dumps(data))       #经过json解码后,原tuple类型转化成list类型

    [{'a': 'Aasdf', 'b': [2, 4], 'c': 3.0}]

    #编码过程中,Python中的listtuple都被转化成json的数组,而解码后,json的数组最终转化为Pythonlist,无论原来是list还是tuple

    2)从jsonPython的类型转化

    JSON字符串类型

    Python类型

    object

    dict

    array

    list

    string

    unicode

    number(int)

    int

    uumber(real)

    float

    true

    True

    false

    False

    null

    None

    >>> a = [{1:12, 'a':12.3}, [1,2,3], (1,2), 'asd', 'ad', 12, 13, 3.3,True,False,None]

    >>> json.dumps(a)

    '[{"1": 12, "a": 12.3}, [1, 2, 3], [1, 2], "asd", "ad", 12, 13, 3.3, true, false, null]'

    >>> json.loads(json.dumps(a))

    [{'1': 12, 'a': 12.3}, [1, 2, 3], [1, 2], 'asd', 'ad', 12, 13, 3.3, True, False, None]

    注意:

    json格式的字符串解码成Python对象以后,String类型都变成了Unicode类型,数组变成了list,不会回到原来的元祖类型,字典key的字符类型也被转成Unicode类型。

     

     

    8、JSON编码

    1). 使用json.dumps()方法来将一个Python数据类型列表编码成json格式的字符串。

    json.dumps()                      #将dict类型,转换为json串

    >>> print(json.dumps(s1))               #在上面已说明,s1是字典类型

    {"name": "liuyujing", "age": "18"}

    >>> type(s1)

    <class 'dict'>

    >>> s2 = json.dumps(s1)                #json.dumps()将字典类型转换为json串

    >>> print(s2)

    {"name": "liuyujing", "age": "18"}

    >>> print(type(s2))

    <class 'str'>

    >>> s2

    '{"name": "liuyujing", "age": "18"}'

        2)从Python到JSON字符串类型转化

    >>> import json

    >>> data = [{'a':"A",'b':(2,4),'c':3.0}]

    >>> res = repr(data)             #有什么用?

    >>> print("data :", res)

    data : [{'a': 'A', 'b': (2, 4), 'c': 3.0}]

    >>> data_json = json.dumps(data)

    >>> print(data_json)

    [{"a": "A", "b": [2, 4], "c": 3.0}]

    #观察两次打印的结果,会发现Python对象被转成JSON字符串以后,跟原始的repr()输出的结果会有些特殊的变化,原字典中的元祖被改成了json类型的数组。

    在json编码的过程中,会存在从Python原始类型转化json类型的过程,但这两种语言的类型存在一些差异,对照表如下:

    Python类型

    JSON字符串类型

    dict

    object

    list,tuple

    array

    str,Unicode

    string

    int,long,float

    number

    True

    true

    False

    flase

    None

    null

    json.dumps支持将以上Python类型转换为JSON字符串类型

    >>> json.dumps({1:2})             #会自动将dict的key值加上””

    '{"1": 2}'

    >>> json.loads(json.dumps({1:2}))   #loads后,原dict中的key值的””依然存在

    {'1': 2}

    >>> json.dumps([1,2])             #将list转换为数组(array)

    '[1, 2]'

    >>> json.dumps((1,2))             #将tuple转化为数组(array)

    '[1, 2]'

    >>> json.dumps(["hehe"])

    '["hehe"]'

    >>> json.dumps(["1",2,{1:2},("asx")]) 

    '["1", 2, {"1": 2}, "asx"]'         #依次将list中的每个元素转换为对应的JSON字符串类型

    >>> json.dumps(["1",2,{1:2},("asx","jing")])

    '["1", 2, {"1": 2}, ["asx", "jing"]]'      

    >>> type(("asx"))                

    <class 'str'>

    >>> json.dumps(True)

    'true'

    >>> json.loads(json.dumps(True))

    True

    >>> json.dumps(False)

    'false'

    >>> json.loads(json.dumps(False))

    False

    >>> json.dumps(None)

    'null'

    >>> json.loads(json.dumps(None))#无返回值

    >>>                                   

    >>> print(json.loads(json.dumps(None)))
    None

    3) Json.dumps()

    函数原型

    9、eval                               #将json串转换为dict

    >>> s                                  #s是个json串

    '{"name":"liuyujing","age":"18"}'

    >>> eval(s)                             #eval()可以将json串转换为dict

    {'name': 'liuyujing', 'age': '18'}

    >>> s                                  #经过eval后的s没有什么变化

    '{"name":"liuyujing","age":"18"}'

    >>> print(type(eval(s)))                  #eval()可以将json串转换为dict

    <class 'dict'>

     10、json编码

    函数原型:

    dumps(obj, skipkeys = False, ensure_ascii= True, check_circular=True, allow_nan = True, cls = None, indent = None, separators = None, encoding = “utf- 8”, default = None,sort_keys = False, **kw)

    该方法返回编码后的一个json字符串,是一个str对象encodejson.

    dumps函数的参数很多,但是不是所有的都必须弄清楚,下面只说明几个比较常用的参数。

         1) sort_keys:

    是否按字典排序(a到z)输出。因为默认编码成json格式字符串后,是紧凑输出,并且也没有顺序的,不利于可读。

    >>> data = [{"a":"A","x":(2,4),"c":3.0,"b":"4"},]

    >>> json.dumps(data)

    '[{"a": "A", "x": [2, 4], "c": 3.0, "b": "4"}]'      #key值无顺序

    >>> json.dumps(data,sort_keys =  True)  #按照key值排序输出,且也转化为Json字符

    '[{"a": "A", "b": "4", "c": 3.0, "x": [2, 4]}]'      #串类型

    >>> data = {1:2,53:4,5:6}

    >>> json.dumps(data,sort_keys = True)

    '{"1": 2, "5": 6, "53": 4}'                   #依然会按照key值排序

    >>> data = {1:2,53:4,"a":6}               #key值存在两种类型

    >>> json.dumps(data,sort_keys = True)

    TypeError: '<' not supported between instances of 'str' and 'int' 

    #报错,在int与str之间无法比较<

    >>> data = {"1":"2","53":4,"a":6}          #key值都是str,有数字也有字母

    >>> json.dumps(data,sort_keys = True)

    '{"1": "2", "53": 4, "a": 6}'                 #能够排序

    >>> ord("53")                        

    Traceback (most recent call last):

      File "<stdin>", line 1, in <module>

    TypeError: ord() expected a character, but string of length 2 found

    TypeError: ord()期望得到一个字符,但是找到了长度为2的字符串

    2) indent:

    设置参数缩进显示的空格数。缩进显示使读起来更加清晰。

    >>> data = {"1":"2","53":4,"a":6}

    >>> json.dumps(data,sort_keys = True,indent = 3)  #无print.换行输出

    '{    "1": "2",    "53": 4,    "a": 6 }'

    >>> print(json.dumps(data,sort_keys = True,indent = 3))

    {

       "1": "2",

       "53": 4,

       "a": 6

    }                                             #有print,每层缩进3格

    >>> data = {"1":"2","53":[1,2,3,4,5,6],"a":6}        #”53”key的值是一个数组

    >>> print(json.dumps(data,sort_keys = True,indent = 3))  #设置输出每层缩进3

    {

       "1": "2",                                   #”1”,”a”,”53”是一层,

       "53": [                                    #[1,2,3,4,5,6]是第二层

          1,                                     #遇到{}[],会换行

          2,

          3,

          4,

          5,

          6

       ],

       "a": 6

    }

    3) separators:

    separators:参数的作用是去掉逗号”,”和分号”;”后面的空格,从上面的输出结果都能看到”,”与”:”后面都有个空格,这都是为了美化输出结果的作用,但是在我们传输数据的过程中,越精简越好,冗余的东西全部去掉,因此就可以加上separators参数对传输的json串进行压缩。该参数是元祖格式的。

    >>> data = {"1":"2","53":4,"a":6}

    >>> json.dumps(data)

    '{"1": "2", "53": 4, "a": 6}'                  #”:”和”,”后都有空格

    >>> len(json.dumps(data))                #不去掉”:”和”,”后的空格,长度是27

    27

    >>> json.dumps(data,separators = (",",":"))

    '{"1":"2","53":4,"a":6}'                     #json串进行了压缩,在”:”和”,”后都没有空格

    >>> len(json.dumps(data,separators = (",",":")))#去掉空格,长度是22

    22

    #从结果看出,通过移除多余的空白字符,达到了压缩数据的目的。

    #海量数据处理时,很重要,能省很多字节

    >>> len(json.dumps(data,separators = (",")))

    Traceback (most recent call last):

      File "<stdin>", line 1, in <module>

      File "D:Python36libjson\__init__.py", line 238, in dumps

        **kw).encode(obj)

      File "D:Python36libjsonencoder.py", line 154, in __init__

        self.item_separator, self.key_separator = separators

    ValueError: not enough values to unpack (expected 2, got 1)

                                            #报错,separators后面必须俩参数

    4) skipkeys:

    在encoding过程中,dict对象的key只可以是基本数据类型(str,Unicode,int,long,float,bool,None),如果是其他类型,那么在编码过程中就会抛出TypeError的异常。skipkeys可以跳过那些非string对象的key的处理,就是不处理。

    >>> data= [ { 'a':'A', 'b':(2, 4), 'c':3.0, (1,2):'D tuple' } ]

    >>> print(u"不设置skipkeys 参数")

    不设置skipkeys 参数

    >>> try :

    ...     res1 = json.dumps(data)           #skipkeys参数默认为False时

    ... except Exception as e:

    ...     print(e)

    ...

    keys must be a string

    >>> print(u"设置skipkeys 参数")

    设置skipkeys 参数

    >>> print(json.dumps(data, skipkeys=True))   # skipkeys=True时

    [{"a": "A", "b": [2, 4], "c": 3.0}]     #不处理key值是(1:2)的数据

    #list,set,dict不能做字典的key,tuple和类的实例可以做字典的key,所以skipkeys基本也就是跳过了tuple和类的实例

    >>> data = [{"sr":2,(1,2):1,p:1},1]

    >>> json.dumps(data,skipkeys = True)

    '[{"sr": 2}, 1]'

    5) ensure_ascii:

    表示编码使用的字符集,默认是True,表示使用ascii码进行编码。如果设置为False.就会以Unicode进行编码。由于解码json字符串时返回的就是Unicode字符串,所以可以直接操作Unicode字符,然后直接编码Unicode字符串,这样会简单些。

    >>> json.dumps("中国")       #默认使用ascii码进行编码,中文不可直接使用

    '"\u4e2d\u56fd"'

    >>> json.dumps("中国",ensure_ascii = False)

    '"中国"'                      #使用unicode进行编码,中文可以直接使用

    11、将类对象(实例)编码成Json串

    Python中的dict对象可以直接序列化为json的{},但是很多时候,可能用class表示对象,比如定义Employe类,然后直接去序列化就会报错。原因是类不是一个可以直接序列化的对象,但我们可以使用dumps()函数中的default参数来实现。

    >>> json.dumps({1:2})        #Python中的dict对象可以直接序列化为json的{}

    '{"1": 2}'

    >>> json.dumps([{1:2}])       #注意区别以上的例子

    '[{"1": 2}]'

    import json

    class Employee(object):      #定义类Employe

        def __init__(self, name, age, sex, tel):

            self.name = name

            self.age = age

            self.sex = sex

            self.tel = tel

        def obj_json(self, obj_instance): #定义方法obj_json,参数obj_instance,就是实例对象

            return {

            'name': obj_instance.name,

            'age': obj_instance.age,

            'sex': obj_instance.sex,

            'tel': obj_instance.tel }

    emp = Employee('Lily', 24, 'female', '18223423423')

    print(json.dumps(emp, default = emp.obj_json)) 

    # {"name": "Lily", "age": 24, "sex": "female", "tel": "18223423423"}

    #emp实例首先使用emp.obj_json方法,拼成了一个dict,搞成了一个json串。

    12、JSON反序列化为类对象

    json串反序列化成类对象或者类的实例,使用的是loads方法中的object_hook参数来实现。

    import json

    class Employee(object):

        def __init__(self, name, age, sex, tel):

            self.name = name

            self.age = age

            self.sex = sex

            self.tel = tel

    emp = Employee('Lily', 24, 'female', '18223423423')

    def jsonToClass(emp):   # jsonToClass是函数,不是方法,emp是dict,不是实例

        return Employee(emp['name'], emp['age'], emp['sex'], emp['tel'])

    json_str = '{"name": "Lucy", "age": 21, "sex": "female", "tel": "15834560985"}' #json串

    e = json.loads(json_str, object_hook = jsonToClass)

    json_str作为一个参数,先转化为字典,然后传递给jsonToClass,返回一个实例

    print(e)

    print(e.name)

    #<__main__.Employee object at 0x0000020EC3C4E668>

    #Lucy

    小练习:

    1. 匹配ip

    ip = 0.0.0.0

    每一位的数字的范围是0-255

    首先分析ip地址的特征:255.255.255.255;
    1位: 0-9             [0-9] d
    2位:10-99         [1-9]d
    2位以内:            [1-9]?d
    3位:100-199      1d{2}
    3位:200-249      2[0-4]d
    3位:250-255      25[0-5]

    import re

    pattern = r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}("

              r"?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"

    pattern = re.compile(pattern)

    print(pattern.search("255.213.2.345"))

    print(pattern.search("0.0.0.0").group())

    print(pattern.search("2.0.0.0").group())

    (?:)代表括号不代表分组,取消分组,使用group(1)是读不到分组的内容的。

    import re

    print(re.search("a(d)c","a1c").group(1))

    #1

    print(re.search("a(?:d)c","a1c").group(1))

    #IndexError: no such group

    匹配一个单词边界
    (?:pattern)匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)"来组合一个模式的各个部分是很有用。例如"industr(?:y|ies)"就是一个比"industry|industries"更简略的表达式。

    {n}n是一个非负整数。匹配确定的n次。

  • 相关阅读:
    Go语言并发与并行学习笔记(一)
    Tomcat编码问题
    如何为Kafka集群选择合适的Partitions数量
    go局部变量的存储空间是堆还是栈?
    git的一个merge流程
    GO工程和包
    Go运行环境搭建(MacLinux)
    一些Shell命令
    python_17_数据运算
    python_15_os
  • 原文地址:https://www.cnblogs.com/suitcases/p/10830264.html
Copyright © 2011-2022 走看看