正则表达式

Posted 542684416-qq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式相关的知识,希望对你有一定的参考价值。

正则表达式

应用场景

  • 特定规律字符串的查找切割替换等

  • 邮箱格式、URL、IP等的校验

  • 爬虫项目中,特定内容的提取

使用原则

  • 只要使用字符串等函数解决的问题,就不要使用正则

  • 正则的效率比较低,同时会降低代码的可读性。

  • 世界上最难理解的三样东西:医生的处方、道士的神符、码农的正则。

  • 提醒:正则是用来写的,不是用来读的;在不指定功能的情况下,不要试图阅读别人的正则。

基本使用

  • 说明:正则不是我们写的,python中正则的解析通过re模块完成

  • 相关函数:

    • match:从开头进行匹配,匹配到就返回正则结果对象,没有返回None。

    • search:从任意位置匹配,功能同上。

      # 从开头查找,找到返回正则匹配结果对象,没有找到返回None
      # m = re.match(‘abc‘, ‘abcdask;jabcsdajl‘)
      # 从任意位置查找,功能同上
      m = re.search(abc, shdalsjdabchaoeor)
      ?
      if m:
          # 返回匹配的内容
          print(m.group())
          # 返回匹配内容位置
          print(m.span())
    • findall:全部匹配,返回匹配到的内容组成的列表,没有返回空列表。

    # 匹配所有内容,找到返回所有匹配的内容列表,没有找到返回空列表
    f = re.findall(abcd, adsjkjdabcajsdlasabcjsdlaabc)
    print(f)
    compile:生成正则表达式对象
    
    # 先生成正则表达式对象
    c = re.compile(hello)
    # print(type(c))
    ?
    # 从开头匹配
    m = c.match(hellosadk;ask;kahellosadhlkas)
    print(m)
    ?
    # 从任意位置匹配
    s = c.search(hadlsjasdhellokjsdlks)
    print(s)
    ?
    # 匹配所有内容
    f = c.findall(hellosdhasdjahelloshdajldhello)
    print(f)

    说明:此方式更加灵活,将正则匹配分为两步完成(先生成正则对象,然后需要时进行匹配)

正则规则

  • 单个字符

    普通字符:简单来说就是一对一的完全匹配。
    []:中间的任意一个字符
        [a-z]:a~z之间的任意字符(所有的小写字母)
        [a-zA-Z]:匹配所有的字母,多个连续的片段中间不能有任何多余的字符
        [^0-9]:匹配除0-9以外的任意字符
    . :匹配除
    以外的任意字符
    d:数字字符,等价于[0-9]
    D:非数字字符,等价于[^0-9]
    w:匹配字(数字、字母、下划线、汉字)
    W:匹配非字(w相反的内容)
    s:所有的空白字符(
    、	、
    、空格)
    S:非空白字符(s相反的内容)
    :词边界(开头、结尾、空格、标点等)
    B:非词边界(相反的内容)
  • 次数限定

    *:前面的字符出现任意次
    +:至少一次
    ?:最多一次
    {m,n}:m <= 次数 <= n
    {m,}:至少m次
    {,n}:至多n次
    {m}:指定m次
  • 边界限定

    • ^:以指定的内容开头

    • $:以指定的内容结束

    • 示例:

      import re
      ?
      # ^:以指定内容开头
      # f = re.findall(‘^hello‘, ‘hellosjdhelloalskdhello‘)
      ?
      # $:以指定内容结尾
      f = re.findall(hello$, hellosjdhelloalskdhello)
      ?
      print(f)
  • 优先级控制

    • |:表示或,它拥有最低的优先级

    • ():表示一个整体,可以明确的指定结合性/优先级

    • 示例:

      import re
      ?
      f = re.findall(a(hello|world)c, sahdjsahellocaworldcjsdhs)
      ?
      print(f)
  • 分组匹配

    • 示例1:

      import re
      ?
      c = re.compile(r(d+)([a-z]+)(d+))
      ?
      s = c.search(sdsdj235sadhasjd36432sjdha)
      ?
      # 完整匹配结果
      print(s.group(), s.span())
      # 等价于上式
      print(s.group(0), s.span(0))
      # 第几个()匹配的结果
      print(s.group(1), s.span(1))
      print(s.group(2), s.span(2))
      print(s.group(3), s.span(3))
    • 示例2:

      import re
      ?
      # 固定匹配
      # c = re.compile(r‘<a>w+</a>‘)
      ?
      # 1表示前面第一个()匹配的内容
      # c = re.compile(r‘<([a-z]+)><([a-z]+)>w+</2></1>‘)
      ?
      # 给分组()起名字
      c = re.compile(r<(?P<goudan>[a-z]+)><(?P<dahua>[a-z]+)>w+</(?P=dahua)></(?P=goudan)>)
      ?
      s = c.search(<div><a>百度一下</a></div>)
      ?
      if s:
          print(s.group())
  • 贪婪匹配

    • 贪婪:最大限度的匹配。正则的匹配默认就是贪婪的。

    • 非贪婪:只要满足条件,能少匹配就少匹配。‘?‘经常用于取消贪婪

    • 示例:

      import re
      ?
        # ?:取消任意多次的贪婪匹配
        # c = re.compile(r‘a.*?b‘)
      ?
        # ?:取消至少一次的贪婪匹配
        c = re.compile(ra.+?b)
      ?
        s = c.search(ssjdsdabjdsd)
      ?
        if s:
            print(s.group()) 
  • 匹配模式

    • 说明:所谓匹配模式就是对匹配的原则进行整体的修饰。

    • 示例:

      import re
      ?
      # 忽略大小写re.I
      s = re.search(rhello, HELLO world, re.I)
      ?
      # 正则默认是单行匹配,使用 re.M 可以进行多行匹配
      s = re.search(r^hello, sdhasdh
      hello world, re.M)
      ?
      # 使.匹配任意字符,作为单行处理,忽略
      
      # string = ‘<div>hello</div>‘
      string = ‘‘‘<div>
      hello
      </div>‘‘‘
      s = re.search(r<div>.*?</div>, string, re.S)
      ?
      if s:
          print(s.group())

练习

  • 邮箱格式的匹配

    #邮箱格式的匹配
    import re
    c = re.compile(r^[email protected](w+.)+(com|cn|edu|net)$)
    string = [email protected]
    # string = ‘[email protected]
    # string = ‘[email protected]
    s = c.search(string)
    if s:
        print(s.group())
  • 手机号码的匹配

    #手机号码的匹配
    import re
    x = r^(1[3578]d{9}|147d{8})$
    print(re.match(x,18768853995).group())

以上是关于正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

markdown 正则表达式模式片段

正则表达式匹配特定的 URL 片段而不是所有其他 URL 可能性

循环通过 python 正则表达式匹配

asp.net 使用正则表达式验证包含打开/关闭括号片段的属性字符串

攻破难啃的骨头-正则表达式(转)

正则表达式的贪婪和非贪婪模式