美文网首页python编程
Python进阶1 - 正则表达式: 一文掌握正则表达式编程

Python进阶1 - 正则表达式: 一文掌握正则表达式编程

作者: 小马哥China | 来源:发表于2019-06-06 23:50 被阅读0次

    小马哥正在为Python的所有常见知识进行汇总,更会有大量实战项目
    点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容

    导语

    正则表达式本质是一种字符串模式或者叫字符串模板,用来匹配一些列的字符串,找到目标字符串的过程就是匹配或者搜索,找到这些目标字符串之后,就可以对其进行提取,进行拆分,进行替换等等. 这也就是正则表达式和编程语言的逻辑关系,正则表达式规定了如何定义模式,编程语言使用正则表达式确定的逻辑模式,进行功能实现(匹配,搜索,提取,查分,替换等功能).

    主要内容:

    • (2)先使用Python的re模块,实现正则表达式编程
    • (1)正则表达式基本知识点

    我故意把顺序倒过来,虽然先有正则再有Python对正则表达式的支持, 我们先把知识用起来,然后不用太多解释,你已经清楚正则是用来干什么了.目的还是保证: 一篇文章精通正则表达式,以及Python使用正则表达式熟练编程.

    (一)用Python针对正则表达式编程

    先把"见猪跑",直观认识正则表达式与Python利用正则表达式实现一定功能,介绍常用的函数或者方法

    1.1 match()函数

    作用: 匹配正则表达式,如果匹配成功就返回一个匹配对象;如果匹配失败,就返回None. 匹配对象的group()方法用于显示成功的匹配.

    例1,实现最简单的正则表达式,

    import re
    # 正则表达式模式
    pattern = 'China'
    # 字符串文本
    data = 'China'
    # 通过re模块的的match方法,从data的起始部分开始,对正则表达式模式进行比对,如果匹配,返回一个匹配对象;否则返回None
    result = re.match(pattern,data)
    print(type(result))  # 返回 <class 're.Match'>
    print(result.group()) # Match对象的group()会返回成功的匹配.
    

    例2,最简单的正则表达式模式,之如果匹配失败是什么样子的

    import re
    
    pattern = 'China'
    datas= 'Chinese','Python','China is a great country'
    
    for data in datas:
        result = re.match(pattern,data)
        if result is not None:
            print("匹配成功: ",result)
        else:
            print('匹配失败: ',data)
    
    匹配失败:  Chinese
    匹配失败:  Python
    匹配成功:  <re.Match object; span=(0, 5), match='China'>
    

    上面的模式(或者认为是模板)中,pattern就是一个简单的字符串,但是这样的模式只能匹配一个单词,如果想匹配更多的情况,模式应该怎么写?

    例3,能够匹配一个范围的字符

    import re
    pattern = '[abc]'   #使用[]括起来的内容,代表一个集合,代表匹配集合内的任意一个字符,[abc]代表可以匹配a或者b或者c
    datas = 'a','b','c','e','xay'
    
    for data in datas:
        result = re.match(pattern,data)
        if result is not None:
            print('Match Successfully: ',result.group())  # group()函数的作用: 返回Match对象匹配到的字符内容
        else:
            print('Match Failed: ',data)
    
    

    例4,上面的例子中[abc]指代了一个集合,元素之间是或的关系,也可以把这个集合看做一个范围,

    还有一种表示方法[a-z][A-Z][0-9],也是指代范围,[a-c]也是同样的意思

    import re
    pattern = '[a-e]'   #[a-e]代表了a到e这个字符范围内的任何一个字符
    datas = 'a','b','c','e','xay'
    
    for data in datas:
        result = re.match(pattern,data)
        if result is not None:
            print('Match Successfully: ',result.group())  # group()函数的作用: 返回Match对象匹配到的字符内容
        else:
            print('Match Failed: ',data)
    

    例5,点号'.' 匹配任意的单个字符(换行符和非字符除外)

    import re
    pattern = '李.'
    names='李逵','李鬼','小李'
    for name in names:
        isMatched = re.match(pattern,name)
        if isMatched:
            print('Match Successfully: ',isMatched)
        else:
            print('Match Faied: ',name)
    
    Match Successfully:  <re.Match object; span=(0, 2), match='李逵'>
    Match Successfully:  <re.Match object; span=(0, 2), match='李鬼'>
    Match Faied:  小李
    

    1.2 search()函数

    作用: 在字符串中查找指定的模式,返回第一次出现的位置

    match()函数的作用是在目标字符串的起始位置开始匹配,是否符合正则表达式模式. 我们很多场景可能不一定在字符串起始位置,更多情况是在字符内搜索是否有匹配正则模式的字符串存在,这就是search()函数的存在意义了.

    例1,在一段文本中查找目标字符串

    import re
    data = '我爱伟大的祖国,I love China,China is a great country'     #China在data字符串中的位置区间为[15,20)  半开半闭区间
    pattern = 'China'
    result = re.search(pattern,data)
    print(result.group())
    
    print(data[19])
    
    
    China
    a
    

    例2,点号"."的使用,搜索除去换行符之外的任意字符

    import re
    sentence='华为是华人的骄傲'    #1,通过这个句子1可以体会点号的作用;2,search()函数会返回第一次匹配
    pattern='华.'
    result = re.search(pattern,sentence)   
    if result:
        print(result.group())
    
    华为
    

    who laughs last laughs best

    1.3 findall()和finditer()函数

    作用:

    • findall()查询字符串中某个正则表达式全部的非重复出现情况,返回的是一个列表.
    • finditer()返回的是一个迭代器,所以相比findall()更加节省内存
    import re
    sentence='华为是华人的骄傲'
    pattern = '华.'
    result = re.findall(pattern,sentence)
    print(result)
    
    ['华为', '华人']
    
    import re
    sentence = '华为是华人的骄傲'
    pattern = '华.'
    result = re.finditer(pattern,sentence)
    print(type(result))
    
    <class 'callable_iterator'>
    
    
    

    1.4 group()和groups()方法

    作用: 匹配对象的两个方法

    • 匹配对象: match()或者search()成功调用后返回的对象

    • 子组: 圆括号对匹配模式的各个部分进行分组和提取操作,子组可以带来的方便是,不用通过match之后,再来对特定字符串进行抽取

    • group(): 返回整个匹配对象或者返回特定的子组

    • groups(): 返回一个包含唯一或者全部子组的元组

    • 如果没有子组的要求,那么当group()仍然返回整个匹配时,groups()返回一个空元组.

    例1,无子组的模式返回使用group()匹配对象

    import re
    pattern = 'a'
    data = 'abcd'
    result = re.match(pattern,data)
    print(result)
    print(result.group())
    print(result.groups())
    
    <re.Match object; span=(0, 1), match='a'>
    a
    ()
    
    import re
    pattern = '(华.)\w(华.)'
    sentence = '华为是华人的骄傲'
    result = re.search(pattern,sentence)
    print(result)
    print(result.group())  #返回整个匹配对象
    print(result.group(0)) #返回整个匹配对象
    print(result.group(1)) #返回子组1
    print(result.group(2)) #返回子组2
    print(result.groups()) #返回包含所有子组的元组
    
    <re.Match object; span=(0, 5), match='华为是华人'>
    华为是华人
    华为是华人
    华为
    华人
    ('华为', '华人')
    

    1.5 compile()函数

    作用: 编译正则表达式

    import re
    pattern = '(华.)\w(华.)'
    sentence = '华为是华人的骄傲'
    compiled_pattern = re.compile(pattern)  #<class 're.Pattern'>
    print(type(compiled_pattern))
    # result = re.match(compiled_pattern,sentence)   #(-1-)这样做,
    result = re.match(pattern,sentence)       # (-2-)<class 're.Match'>
    print(result)#(-1-)(-2-)得到的结果都是一样的,但是在多次用到compiled_pattern的时候,会节省了编译pattern的这个过程
    
    <class 're.Pattern'>
    <re.Match object; span=(0, 5), match='华为是华人'>
    

    1.6 sub()和subn()函数

    作用: 实现搜索和替换(找到目标字符串,然后替换掉)

    sub()完成替换,返回一个被替换完成之后的字符串

    subn()完成替换,还返回被替换的数量,字符串和数组,组成元组返回

    import re
    sentence = 'Java是很受欢迎的编程语言'
    pattern = '[a-zA-Z]+'   # [字符集范围]   " + "代表: 前面的模式出现1次以上
    
    result = re.sub(pattern,'Python',sentence)  # 使用新的Python替代
    print(result)
    resultn = re.subn(pattern,'Python',sentence)
    print(resultn)
    
    Python是很受欢迎的编程语言
    ('Python是很受欢迎的编程语言', 1)
    
    import re
    sentence = 'Java是一门强大的语言,Go前途不错'
    pattern = 'Java|Go'  # 或关系
    result = re.sub(pattern,'Python',sentence)
    print(result)
    
    Python是一门强大的语言,Python前途不错
    

    1.7 split()

    作用: 实现分隔字符串

    import re
    data = '百度,腾讯,阿里,华为,智能天下'
    pattern = ','
    result = re.split(pattern,data)
    print(type(result))
    print(result)
    
    <class 'list'>
    ['百度', '腾讯', '阿里', '华为', '智能天下']
    

    (二) 正则表达式的知识点汇总

    介绍正则的知识点,用于编辑正则表达式,

    2.1 正则模式中的字符

    • 最简单的,任意一个字符串都是一个正则表达式的模式(但是这样的通用性不强,只能匹配一个特定字符串,没有什么意义)

    • 匹配一定范围内的单个字符1[abc]: 中括号里面的内容即"或"的关系

    • 匹配一定范围内的单个字符2[a-c]: 使用连接符,代表范围,[a-z][0-9]

    • 代表单个字符的特殊符号:

      1. "."点号: 匹配任意字符(字母,数字,特殊字符,但是换行符除外)

      2. \w: 匹配任意字母,数字(比上面的"."少了特殊字符)

      3. \d: 匹配任意十进制数字(比上面的\w少了字母)

      4. \s: 匹配空白

      5. \b: 匹配边界

      6. ^: 匹配开始

      7. $: 匹配结尾

      8. 注意: 如果要在模式中匹配上面出现的特殊字符,例如: ".","","^","$",需要使用转义字符:\

    2.2 正则中频数的表示

    概括的表示频数

    • *: 代表匹配0次或者多次
    • +: 代表匹配1次或者多次
    • ?: 代表匹配0次或者一次

    精确的表示频数

    • {n}: 代表前面的模式出现n次
    • {m,n}: 代表前面的模式出现m到n次之间

    2.3 其它重要知识点

    分组

    模式中被"()"括起来的内容,是可以被提取的,Python以及各种语言实现了这种功能,group()

    模式的逻辑或与否定

    1. "|" 代表两个模式的或关系

      例如: bat|tmd 可以匹配:bt,bm,bd,at,am,ad,tt,tm,td

      同: [bat][tmd]

    2. "^" 除匹配字符串的开始之外,如果用在[]中,代表否定的意思

      例如: [\d]代表的是一个十进制数,[^\d]代表除十进制数之外的其它模式

    正则表达式的扩展表示法

    2.4 转义字符与原始字符串

    转义字符: \ 在字符串中,转义字符用于输出一些特殊字符,例如:\b,代表的是退格,\n代表换行,\t代表制表符,本质上,字符串的转义字符,是为了打印准备的,所以我们暂且定义: 字面量和打印量

    原始字符串: 把字母"r"放在字符串开头,代表这是一个原始字符串,它的作用在于消除字符串和正则表达式之间各自关于转义的歧义,例如: \b在正则中表示边界

    在cmd窗口里面,定义一个字符串data = '\',输入data与print(data)得到的是不一样的结果,前者是'\',后者是'',这就是字面量和打印量的区别

    这个时候再来解释转义在字符串中和正则中的歧义问题就明了了

    data = 'ab\cd' # 现在需要要匹配出data中的\怎么处理

    首先,data的字面量,也就是字符串的真实值看似是'ab\cd',其实,你用cmd窗口,直接输出data而不是print(data),会发现,字符串的字面显示: ab\cd
    所以要匹配出来data的'',pattern要如何写呢?

    pattern1 = ''

    pattern2 = '\'

    pattern3 = '\\'

    结果是第三个,首先pattern是一个字符串,虽然要交给正则表达式引擎去解析,但是终归是一个字符串,那么就要经过字符串的转义处理,第一个语法错误,这个''首先转义了结尾的"'",字符串没有结尾了;第二个,'\'是正确的字符串,经过字符串转义后,字面量是\,传递给正则引擎的时候和打印的时候一样,是'',但是真实的data字面量是'\',肯定匹配不到,于是只能用第三种

    小马哥正在为Python的所有常见知识进行汇总, 更会有大量实战项目
    点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容

    相关文章

      网友评论

        本文标题:Python进阶1 - 正则表达式: 一文掌握正则表达式编程

        本文链接:https://www.haomeiwen.com/subject/hmvpxctx.html