zoukankan      html  css  js  c++  java
  • 正则表达式

    正则表达式

      正则表达式,又称规则表达式是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个规则的文本。以往对字符数据处理时通常使用字符串函数,当我们了解正则表达式后,会发现正则表达式简单高效。正则表达式在不同的语言中使用方法不同,本质上区别不大。在Python语言中使用正则时需要导入模块re,下面内容主要概述基本使用方法。

    re.match函数

      re.match 从字符串的起始位置匹配一个模式,如果起始位置没有匹配成功match()就返回none;如果匹配成功就返回匹配对象Match Object,然后可以通过对象具有的方法group()提前字符串匹配的部分。

     re.match(pattern, string, flags=0)

      pattern:匹配的正则表达式

      string:要匹配的字符串

      flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

    import re
    
    s = "love Python3"
    result = re.match("lov", s)
    print(result)
    print(result.group())
    
    output:
    <re.Match object; span=(0, 3), match='lov'>
    lov

    常见匹配字符

    单字符匹配

    >>> re.match(".","abc").group()
    'a'
    >>> re.match("[aA]","abc").group()
    'a'
    >>> re.match("[0-9]","123abc").group()
    '1'
    >>> re.match("今天d号","今天3号").group()
    '今天3号'

    匹配多个字符的相关格式---表数量

    >>> re.match("[A-Za-z]*","Shanghai").group()
    'Shanghai'
    >>> re.match("[A-Za-z]+w","Shanghai_55").group()
    'Shanghai_'
    >>> re.match("[A-Za-z]+w*","Shanghai_55").group()
    'Shanghai_55'
    #匹配0-99
    >>> re.match("[1-9]?[0-9]","99").group()
    '99'
    >>> re.match("w{6}","1343a_de454").group()
    '1343a_'
    >>> re.match("w{6,9}","1343a_de454").group()
    '1343a_de4'
    >>> re.match("w{6,}","1343a_de454").group()
    '1343a_de454'

    边界匹配

    >>> re.match(".*\bllo\b","he llo world").group()
    'he llo'
    >>> re.match(r".*llo","he llo world").group()
    'he llo'

      在正则表达式中“”通常作为转义字符出现,如单词边界分隔符"",在使用时需要双\。如果出现多个反斜杠岂不是很麻烦,可能造成漏写,因此Python里的原生字符串很好地解决了这个问题,即在字符串前面使用r,这样写出来的表达式更加直观了。

    >>> re.match(r".*llo","hello world").group()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'
    >>> re.match(r".*llo","he lloworld").group()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'

      匹配单词边界,要求匹配的字符要么位于首端、末端或者字符两端空格。

    >>> re.match(r".*lloB","lloh").group()
    'llo'
    >>> re.match(r".*BlloB","helloh").group()
    'hello'
    >>> re.match(r".*BlloB","hello").group()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'
    >>> re.match(r".*Bllo","llo").group()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'

    B匹配非单词边界,要求匹配的字符不能位于首端、末端或者有空格。

    匹配分组

     

    #匹配0-100
    >>> re.match(r"[1-9]?d$|100","92").group()
    '92'
    #匹配分组
    >>> re.match("([^-]*)-(d+)","0761-3601110").group()
    '0761-3601110'
    >>> re.match("([^-]*)-(d+)","0761-3601110").groups()
    ('0761', '3601110')
    >>> re.match("([^-]*)-(d+)","0761-3601110").group(1)
    '0761'
    >>> re.match("([^-]*)-(d+)","0761-3601110").group(2)
    '3601110'

    分组匹配:<html><h1>www.baidu.cn</h1></html>

    • umber
    >>> s = "<html><h1>www.baidu.cn</h1></html>"
    >>> re.match(r"<(w*)><(w*)>.*</2></1>",s).group()
    '<html><h1>www.baidu.cn</h1></html>'

    前后标签一致可以使用分组(),第一个分组为1,第二个为2,依次类推。

    • (?P<name>) (?P=<name>)
    >>> s = "<html><h2>www.baidu.cn</h2></html>"
    >>> re.match(r"<(?P<lab1>w*)><(?P<lab2>w*)>.*</(?P=lab2)></(?P=lab1)>",s).group()
    '<html><h2>www.baidu.cn</h2></html>'

      ?P定义分组别名name,?P=为使用分组别名。当使用的分组较多时,用 umber不够直观可能会出错,使用分组别名替代 umber更加直观可以避免混乱。

     search方法

      search扫描整个字符串并返回第一个成功的匹配字串,search方法和match方法的区别就是match从头开始匹配。

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

      pattern:匹配的正则表达式

      string:要匹配的字符串

      flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

    >>> s = "Cats are smarter than dogs"
    >>> re.search(r"smarter", s).group()
    'smarter'
    >>> re.search(r"d+","一年365天").group()
    '365'

    findall方法

      在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。 match 和 search 是匹配一次 findall 匹配所有。

    findall(pattern, string, flags=0):

      pattern:匹配的正则表达式

      string:要匹配的字符串

      flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

    >>> re.findall(r"d+","android9,python3,java10")
    ['9', '3', '10']

    finditer方法

    与findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

    finditer(pattern, string, flags=0)

      pattern:匹配的正则表达式

      string:要匹配的字符串

      flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

    s = "android9,python3,java10"
    it = re.finditer(r"d+", s)
    for res in it:
        print(res.group())
    
    output:
    9
    3
    10

    split方法

    方法按照能够匹配的子串将字符串分割后返回列表。

    split(pattern, string[, maxsplit=0, flags=0])

      pattern:匹配的正则表达式

      string:要匹配的字符串

      maxsplit:分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。

      flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

    >>> re.split(r":| ","info:xiaoming Shanghai 27")
    ['info', 'xiaoming', 'Shanghai', '27']

    sub方法

    re.sub用于替换字符串中的匹配项。

    re.sub(pattern, repl, string, count=0)

      pattern : 正则中的模式字符串。

      repl : 替换的字符串,也可为一个函数。

      string : 要被查找替换的原始字符串。

      count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

    #删除非数字内容
    >>> re.sub(r"D","","2018-12-31")
    '20181231'
    >>> re.sub(r"-",".","2018-12-31")
    '2018.12.31'

    repl为函数时:

    def add(temp):
        print("---add---")
        str_num = temp.group('value')
        num = int(str_num) + 1
        return str(num)
    
    ret = re.sub(r"(?P<value>d+)", add, "python = 2,Android8")
    print(ret)
    
    output:
    ---add---
    ---add---
    python = 3,Android9

    贪婪和非贪婪模式

      Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。

    >>> s = "This is a number 234-235-22-423"
    #贪婪
    >>> re.match(r".+(d+-d+-d+-d+)",s).group(1)
    '4-235-22-423'
    #关闭贪婪
    >>> re.match(r".+?(d+-d+-d+-d+)",s).group(1)
    '234-235-22-423'

      在正则表达式中使用通配字符,则在匹配时会尽可能的匹配多的字符,直到分组内4能满足第一个d+才截止;关闭贪婪模式时,分组内的d+会向前延伸获取,即.+?会尽可能的少匹配。

    #从字串中提取网站
    >>> s="""<img data-original="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">"""
    #贪婪
    >>> re.search(r"https.+.jpg",s).group()
    'https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg'
    #非贪婪
    >>> re.search(r"https.+?.jpg",s).group()
    'https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg'

    匹配网站

    >>> s="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg"
    >>> re.sub(r"(https://.+?/).*",lambda temp:temp.group(1),s)
    'https://rpic.douyucdn.cn/'
  • 相关阅读:
    深入理解Java:注解(Annotation)--注解处理器
    Java进阶之reflection(反射机制)——反射概念与基础
    JAVA 动态代理
    注解是建立在class文件基础上的东西,同C语言的宏有异曲同工的效果
    Android 进阶8:进程通信之 Binder 机制浅析
    Android Binder机制(一) Binder的设计和框架
    Android Service初解
    原生sql和 TP sql怎么关联?
    Laravel 修改默认日志文件名称和位置
    laravel asset()函数
  • 原文地址:https://www.cnblogs.com/jsnhdream/p/10201175.html
Copyright © 2011-2022 走看看