写点什么

python 正则 | python 小知识

作者:AIWeker
  • 2023-04-21
    福建
  • 本文字数:1941 字

    阅读完需:约 6 分钟

正则表达式是一种匹配字符串的规则,我们可以通过正则表达式去搜索指定规则的字符串。


如果你有需要匹配字符串,正则是一种选择,特别是匹配规则比较复杂的情况下。正则表达式最常用的地方是爬虫,在爬取网页时,指定你需要爬取的内容。


python 中的模块 re 提供了解析正则匹配的规则。


因为正则规则比较不容易理解,理解了规则也会很快忘记,所以建议是了解常用的使用,有具体的匹配需求再去了解是否有规则可以满足你的要求。

1. 正则的四种规则

所以我们先通过一个简单的例子来了解下 re 正则匹配


import repattern = "\w+"ret = re.match(pattern, "a12323abc")print(ret)# <_sre.SRE_Match object; span=(0, 9), match='a12323abc'>
复制代码


正则规则可以分四种:


  • 单个字符, 如上面例子中\w表示普通字符(数字、字母或下划线);其他如下:


  • 数量, 如上面例子中+表示重复一次或者多次, ?表示重复 0 次或者一次



    • 字符组,就是一组字符,用[]包含起来,如果在一个字符组里枚举所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配


    • 位置: ^表示匹配开头,$表示匹配结尾


    上面例子中"\w+"表示只要是一个或者多个普通字符都算匹配,如何匹配 re.match 返回非 None,否则返回 None


    我们在看一个匹配邮箱的里子



    # @前面是一个或者多个字符,@后面是一个或者多个字符, 接着最后.compattern = "\w+@\w+\.com"ret = re.match(pattern, "yuyq@163.com")print(ret)# <_sre.SRE_Match object; span=(0, 12), match='yuyq@163.com'>
    pattern = "\w+@\w+\.com"ret = re.match(pattern, "yuyqx163.com")print(ret)# None
    pattern = "\w+@(\w+\.)?\w+\.com"ret = re.match(pattern, "hello123@1xheuet..edu.com")print(ret)# None
    复制代码


    从上面例子需要知道:


    • 由于.是正则里的特殊字符,需要转义\.

    • (\w+\.)? 中?表示 0 或者多个,也可以理解有也可以没有也可以,()表示包括的字符是一起的,也就是说 abc.ax. 类似这种是匹配的。上面最后一个例子中多个一个.不符合规则

    2. match 和 search 的区别

    re 除了提供 match,还提供 search,findall,sub,split 等函数;其中 match 和 search,findall 提供搜索匹配,sub 提供替换,split 提供分割。


    那 match 和 search 有什么区别?


    pattern = "(acb)+"ret = re.match(pattern, "dacbbacb1b")print(ret)# None
    ret = re.search(pattern, "dacbbacb1b")print(ret)# <_sre.SRE_Match object; span=(1, 4), match='acb'>
    ret = re.findall(pattern, "dacbbacb1b")print(ret)# ['acb', 'acb']
    复制代码


    上面的例子,待匹配的字符串中明明有 acb 为什么 match 没有匹配成功,原因是:


    • re.match 只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回 None

    • re.search 匹配整个字符串,直到找到一个匹配

    • 而 re.findall 是匹配所有


    我们来看看 sub 和 split 的例子


    import re# ":| "表示用:或者空格匹配,|表示只要匹配其中一个规则就可以ret = re.split(r":| ","info:xiaoZhang 33 shandong")print(ret)# ['info', 'xiaoZhang', '33', 'shandong']
    import re# 如果"python = 997"中的1个或者多个数字(/d)就是997,使用前面的xx替换ret = re.sub(r"\d+", "xx", "python = 997")print(ret)# python = xx
    复制代码

    3. 更多的例子

    我们来看几个个复杂的例子


    # 匹配1-100pattern = "[1-9]?\d$|100"ret = re.match(pattern, "102")print(ret)# None
    复制代码


    规则解说:


    • [1-9]?表示 0 或者 1 个 0 到 9 的其中一个数字,

    • 然后\d表示结尾

    • |100 也是匹配的


    pattern = "[a-zA-Z0-9_]{8,20}"ret = re.match(pattern, "000000000.")print(ret)# None
    复制代码


    规则解说:


    • [a-zA-Z0-9_] 必须是大写字母,小写字母,数字和下划线例的字符

    • {8,20}:数量是 8 到 20 个

    4. 正则的贪婪与⾮贪婪

    正则还有一个匹配原则是最多匹配(贪婪)和最少匹配(⾮贪婪)


    • 正则表达式默认为贪婪匹配,也就是尽可能多的向后匹配字符,比如 {n,m} 表示匹配前面的内容出现 n 到 m 次(n 小于 m),在贪婪模式下,首先以匹配 m 次为目标

    • 而在非贪婪模式是尽可能少的向后匹配内容,也就是说匹配 n 次即可


    贪婪模式转换为非贪婪模式的方法很简单,在元字符后添加?即可实现


    pattern = "b+"ret = re.match(pattern, "bbacb1b")print(ret.group())# bb
    pattern = "b+?"ret = re.match(pattern, "bbacb1b")print(ret.group())# b
    复制代码


    从上面例子可以:


    • 默认是贪婪模式,匹配到最多;规则是一个或者多个 b,有多少个 b 就有输出多少个 b

    • 加?是非贪婪模式,规则是一个或者多个 b,就匹配一个 b

    • 通过 group()输出匹配的字符串

    5. 后记

    正则规则通常很容易忘记,这里提供一个比较清晰的规则备忘,需要使用的可以查看


    • http://c.biancheng.net/python_spider/regexp-syntax.html


    总之,记得有 re 正则这个字符匹配工具,遇到合适场景就可以亮出它。希望对你有帮助!

    发布于: 刚刚阅读数: 4
    用户头像

    AIWeker

    关注

    InfoQ签约作者 / 公众号:人工智能微客 2019-11-21 加入

    人工智能微客(aiweker)长期跟踪和分享人工智能前沿技术、应用、领域知识,不定期的发布相关产品和应用,欢迎关注和转发

    评论

    发布
    暂无评论
    python正则 | python小知识_Python_AIWeker_InfoQ写作社区