美文网首页
正则表达式

正则表达式

作者: 治愈系怪咖 | 来源:发表于2018-11-19 15:36 被阅读0次

    引言

    在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验。

    如何把一个 字符串的特征或者规则告诉计算机,让计算机也能知道我们要描述的是什么样的东西,这个描述的语法就是正则表达式。

    概述

    正则表达式,又称正规表示式、正规表示法、规则表达式、常规表示法(英文:Regular Expression ,在代码中常简写为regex、regexp或RE)。是计算机科学的一个概念。

    正则表达式使用单个字符串来描述、匹配一些列某个句法规则的字符串。

    在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

    Regular Expression 即“描述某种规则的表达式”。

    re模块操作

    在Python中使用正则表达式的工具为re模块。

    re模块的使用

    import re
    
    # 使用match方法进行匹配操作
    result = re.match(正则表达式, 要匹配的字符串)
    
    # 如果上一步匹配到数据,可以使用group方法来提取数据
    result.group()
    

    re.match是用来进行正则匹配检查的方法,从左到右去匹配
    若字符串匹配正则表达式,则match方法返回匹配对象(Match Object)
    否则返回None(注意不是空字符串"")
    匹配对象Match Object具有group方法,用来返回字符串的匹配部分。

    re模块的高级用法

    search

    在字符串当中进行搜索。

    import re
    ret = re.search(r"\d+", "阅读数为:9999")
    ret.group()
    

    运行结果:'9999'

    search方法,从左到右找到第一个匹配的检查就结束,只能拿到第一个。

    findall

    拿到正则匹配的所有结果

    findall返回的是列表类型,显示所有匹配结果

    import re
    ret = re.findall(r"\d+", "python = 9999, c = 7890, c++= 1234")
    print(ret)
    

    运行结果:['9999', '7890', '1234']

    sub

    sub方法是将匹配到的数据进行替换

    sub(规则部分, 要替换的值, 处理的字符串)

    返回新的结果

    import re
    ret = re.sub(r"\d+", "998", "python = 997")
    print(ret)
    

    运行结果:'python = 998'

    要替换的值可以接收一个函数,来执行特定的规则

    import re
    def replace(result):
        # result为正则匹配到的值,所以其有group方法
        r = int(result.group()) + 50
        # 该函数一定要有返回值,返回的只能是字符串类型
        return str(r)
    
    ret = re.sub(r"\d+", replace, "python = 1000, php = 0")
    print(ret)
    

    运行结果:'python = 1050, php = 50'

    split

    根据匹配进行切割字符串,并返回一个列表

    import re
    ret = re.split(r":| ", "info:ly 26 beijing")
    print(ret)
    

    运行结果: ['info', 'ly', '26', 'beijing']

    表示字符

    正则表达式的但字符匹配

    字符 功能
    . 匹配任意1个字符(除了\n)
    [] 匹配[]中列举的字符
    \d 匹配数字,即0-9
    \D 匹配非数字
    \s 匹配空白字符,即 空格、tab键、\t、\n、 \r
    \S 匹配非空白
    \w 匹配单词字符,即a-z、A-Z、0-9、_
    \W 匹配非单词字符

    手机号校验

    import re
    re.match("1[35678]\d\d\d\d\d\d\d\d\d", "13200000000")
    

    []用法特点:

    • 预定义的集合中不能满足个人需求时使用
    • [^345678] 对[]中的所有字符取反
    • [a-z] "-"表示的是一个范围值
    • \d == [0-9]
    • \D == [^0-9]
    • \w == [a-zA-Z0-9_]
    • \W == [^a-zA-Z0-9_]

    表示数量

    匹配多个字符的相关格式

    字符 功能
    * 匹配前一个字符出现0次或者无限次,即 可有可无
    + 匹配前一个字符出现1次或者无限次,即 至少有1次
    ? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
    {m} 匹配前一个字符出现m次
    {m,} 匹配前一个字符至少出现m次
    {m, n} 匹配前一个字符出现从m到n次

    手机号校验优化

    import re
    re.match("1[35678]\d{9}",  "13245678910")
    

    原始字符串描述

    import re
    mm = "C:\\a\\b\\c"
    ret = re.match(r"C:\\a", mm).group()
    print(ret)
    

    输出结果:C:\a

    以后再去写正则表达式的时候,正则的规则前面通常要加上r,忽略掉里面需要转义的地方。

    表示边界

    字符 功能
    ^ 匹配字符串开头
    $ 匹配字符串结尾
    \b 匹配一个单词的边界
    \B 匹配非单词的边界

    手机校验再次优化

    import re
    re.match(r"^1[35678]\d{9}$",  "13245678910")
    

    因为match方法就是从左到右匹配的,所以^在match方法中体现不是很明显

    匹配分组

    字符 功能
    | 匹配左右任意一个表达式
    (ab) 将括号中的字符作为一个分组
    \num 引用分组num匹配到字符串
    (?P<name>) 分组其别名 (<>定义别名
    (?P=name) 引用别名为name分组匹配到的字符串 (=使用别名

    匹配出0-100之间的数字

    import re
    # 使用|管道符
    re.match(r"[1-9]\d?$|0$|100$", "88" )
    # 简化
    re.match(r"[1-9]?\d", "88")
    

    邮箱匹配

    re.match(r"\w{5, 20}+@(163|126|gmail|qq)\.(com|cn|net)$", "tangerine@qq.com")
    

    贪婪和非贪婪

    Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符。

    非贪婪则总是尝试匹配尽可能少的字符。

    *?+{m, n}后面加上?,使贪婪变成非贪婪。

    # 贪婪
    s = "This is a number 234-235-22-423"
    ret = re.match(".+(\d+-\d+-\d+-\d+)", s)
    ret.group(1)
    

    '4-234-22-423'

    # 非贪婪
    ret = re.match(".+?(\d+-\d+-\d+-\d+)", s)
    ret.group(1)
    

    '234-235-22-423'

    相关文章

      网友评论

          本文标题:正则表达式

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