zoukankan      html  css  js  c++  java
  • 15 python re 模块

    1、基础知识

    正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎

    正则表达式的大致匹配流程:依次拿出表达式和文本中的字符比较,

    如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。

    常用的表达式规则
    '.'     默认匹配除
    之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
    '^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","
    abc
    eee",flags=re.MULTILINE)
    '$'     匹配字符结尾, 若指定flags MULTILINE ,re.search('foo.$','foo1
    foo2
    ',re.MULTILINE).group() 会匹配到foo1
    '*'     匹配*号前的字符0次或多次, re.search('a*','aaaabac')  结果'aaaa'
    '+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
    '?'     匹配前一个字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次
    '{m}'   匹配前一个字符m次 ,re.search('b{3}','alexbbbs').group()  匹配到'bbb'
    '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
    '|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
    '(...)' 分组匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 结果为'abcabca45'
    
    
    'A'    只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"alexabc") 或^
    ''    匹配字符结尾,同$ 
    'd'    匹配数字0-9
    'D'    匹配非数字
    'w'    匹配[A-Za-z0-9]
    'W'    匹配非[A-Za-z0-9]
    's'     匹配空白字符、	、
    、
     , re.search("s+","ab	c1
    3").group() 结果 '	'
    
    '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","37
    re的匹配语法有以下几种
    re.match 从头开始匹配
    re.search 匹配包含
    re.findall 把所有匹配到的字符放到以列表中的元素返回
    re.split 以匹配到的字符当做列表分隔符
    re.sub 匹配字符并替换
    re.fullmatch 全部匹配

     2、re方法:

    2.1、re.match

    
    从开头位置匹配,匹配成功只返回一个,返回的是对象
    若要显示值。group() 返回被 RE 匹配的字符串
    
    re.match语法:re.match(pattern,string,flags=0)
    
    pattern:匹配的正则表达式,string:要匹配的字符串,flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
    s = 'abc1d3e'
    print(re.match('[a-z]',s).group())
    print(re.match('[0-9]',s))
    
    >a
    >None

     2.2、re.search(pattern,string ,flags=0)

    re.search(pattern, string, flags=0)
    
    用于查找字符串中可以匹配成功的子串,从string的开始位置匹配到结尾,匹配成功则返回一个匹配结果不再向后匹配了,如匹配失败则返回None。
    
    
    pattern = re.search('w','aw,bw,cw,dw')  #匹配结果
    print(pattern) #返回一个match对象
    print(pattern.group()) #获取一个分组截获的字符串
    print(pattern.start()) #截获字符串的开始索引
    print(pattern.end()) #截获字符串的结束索引
    >w
    >1
    >2
    • group() 返回被 RE 匹配的字符串
    • start() 返回匹配开始的位置
    • end() 返回匹配结束的位置
    • span() 返回一个元组包含匹配 (开始,结束) 的位置

     2.3、re.findall(pattern,string,flags=0)

    re.findall(pattern, string, flags=0)
    
    搜索string,以列表的形式返回全部能匹配到的字串。
    
    s = 'abc1d3e'
    print(re.findall('[a-z]',s))
    
    print(re.findall('[0-9]','a1b2c3'))
    
    print(re.findall('d+','a21b32c35'))
    #以列表的形式返回所有匹配的子串,d+为匹配1到多个数字
    
    输出结果:
    ['a', 'b', 'c', 'd', 'e']
    ['1', '2', '3']
    ['21', '32', '35']

     2.4、re.finditer(patter,string,flag=0)

    re.finditer(pattern, string, flags=0)
    
    搜索string,返回访问每一个匹配结果的match对象的迭代器
    
    pat = re.finditer('d+','aa123bb456cc')  #返回match对象的一个迭代器
    print(pat)
    
    for i in pat:     #循环迭代器取值
      print(i.group())
    
    >
    <callable_iterator object at 0x0000000002696A90>
    123
    456

     2.5、re.sub()

    re.sub(pattern, repl, string, count=0, flags=0)
    
    使用repl替换string中每一个匹配的子串后返回替换后的字符串。count用于指定最多替换的次数,默认时时全部替换。
    
    pat = re.sub('d+','@@@','aaa1bbb22ccc333')
    print(pat)   #替换匹配对象
    print(re.sub('d+','@@@','aaa1bbb22ccc333',count=2))
    
    >
    aaa@@@bbb@@@ccc@@@
    aaa@@@bbb@@@ccc333
    有加号时 把1 22 333 看成一个整体
    没有就会单个,,,每个都会替换 aaa@@@bbb@@@@@@ccc@@@@@@@@@
    'd'没有+,结果不一样

     2.6、re.compile()

    re.compile(pattern,flags=0)
    
    编译一个正则表达式模式,返回一个模式对象
    
    import re
    re1 = re.compile(r'hello')   #编译一个正则匹配模式
    print(type(re1))
    print(re.match(re1,'hello world').group())
    
    >
    <class 're.Pattern'>
    hello

     2.7、re.spilt()

    re.spilt
    
    re.split(pattern, string[, maxsplit])
    按照能够匹配的子串将string分割后返回列表。
    
    maxsplit用于指定最大分割次数,不指定将全部分割。
    
    import re
    
    s='9-2*5/3+7/3*99/4*2998+10*568/14'
    print(re.split('[*-/+]',s))
    
    print(re.split('[*-/+]',s,3))#分割三次
    >
    ['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
    ['9', '2', '5', '3+7/3*99/4*2998+10*568/14']

     2.8、re.fullmath

    re.fullmatch(pattern, string, flags=0)
    
    整个字符串匹配成功就返回re object, 否则返回None
    
    re.fullmatch('w+@w+.(com|cn|edu)',"alex@oldboyedu.cn")

     3、练习题

    # 1 验证手机号是否合法
    import re
    # phone_number = input('phone_number:>').strip()
    # print('phone_number:>',type(phone_number))
    # if re.findall('1[0-9]{10}',phone_number):
    #     print('合法')
    
    # 2 验证邮箱是否合法
    #
    import re
    # email = input('email:>').strip()
    # if re.fullmatch('^w+@w+.[a-zA-Z]{3}$',email):
    #     print('email合法')
    # 3 开发一个简单的python计算器,实现加减乘除及拓号优先级解析
    #用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
    # 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),
    # 运算后得出结果,结果必须与真实的计算器所得出的结果一致
    (1). 读取文件a.txt,匹配文中所有ip地址,将所有ip地址加入到一个列表中,打印该列表。
    
    import re
    
    li = []
    with open("a","r") as f:
    for line in f:
    result = re.findall(r'd+.d+.d+.d+', line)
    if result:
    li += result
    print(li)
    
    (2). s = '123.33sdhf3424.34fdg323.324',计算字符串中所有数字的和
    本题结果应为:123.33+3424.34+323.32
    
    import re
    s = '123.33sdhf3424.34fdg323.324sss12'
    obj = re.findall(r'd+.d+|d+',s)
    
    start = 0
    for i in obj:
    start += float(i)
    print(start)
  • 相关阅读:
    (OK) Android graphic (12)—display上层相关概念、关系
    (OK) Android系统启动-SystemServer下篇
    (OK) Android系统启动-SystemServer上篇
    (OK) Android 5 SystemServer 各个系统Manager-startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
    Android 6.0 源码分析
    (OK) android6.0源码分析之Runtime的初始化
    (OK) Android的JNI_OnLoad简介与应用
    (OK) Android架构实例分析之注册hello HAL的JNI方法表
    (OK) Android的NDK开发(1)————Android JNI简介与调用流程
    (OK) android-5.0 sensor工作原理—sensorservice的启动(二)
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9520944.html
Copyright © 2011-2022 走看看