美文网首页
python与正则表达式 2020-01-02(未经允许,禁止转

python与正则表达式 2020-01-02(未经允许,禁止转

作者: 9_SooHyun | 来源:发表于2020-01-02 16:17 被阅读0次

    正则表达式

    正则表达式与程序语言无关。正则表达式做匹配实际上就做3件事【字符匹配】+【次数匹配】+【逻辑匹配】
    下面分别进行叙述

    正则表达式中的字符匹配

    字符匹配可以通过通配符匹配实现,也可以通过[]集合匹配实现,而[]集合是更加直观的一种

    • 通配符匹配

      • . 匹配除换行符外的任意单个字符(万能符)
      • \d 匹配任意单个数字
      • \w 匹配任意单个字母
      • \s 匹配任意单个空白字符,如空格、制表符(\t)、换行符(\n)等
    • 基于[]表达式的自定义集合匹配

    使用方括号[]包含若干个字符,可以匹配[]集合中的任意一个字符;用 [^ ] 包含一系列字符,则能够匹配除[]集合字符外的任意单个字符。注意,都是匹配单个字符
    eg.
    [abc]可以匹配'a', 'b', 'c'的任意一个
    [a-z]可以匹配任意一个小写字母
    [a-zA-Z]可以匹配任意一个字母
    [a-zA-Z0-9]可以匹配任意一个字母或数字
    [^a-zA-Z0-9]可以匹配任意一个非数字且非字母的字符

    注意,在方括号[]中,除了^表示取反外,一切字符都表示字符本身,没有特殊功能,小括号()在[]中也只表示字符 '(' 和 ')',没有分组功能

    正则表达式中的次数匹配

    相似地,次数匹配可以使用通配符匹配,也可以使用自定义{}表达式匹配

    • 次数通配符匹配

      • ? 前置表达式出现0次或者1次,相当于 {0,1},好像在问“出现还是不出现?”。比如:"a[cd]?"可以匹配 "a","ac","ad"

      • + 前置表达式至少出现1次,相当于 {1,},可理解为在1的基础上可以一直+下去。比如: "a+b"可以匹配 "ab","aab","aaab"...

      • * 前置表达式出现任意次,相当于 {0,},比如: "a*b"可以匹配 "b","aaab"...

    • 自定义{}表达式匹配

    使用{}表达式做次数匹配更加直观,也更加灵活,可以自定义次数的上下界,个人更喜欢用
    {n}表示前置表达式重复n次
    {m,n}表示前置表达式至少重复m次,至多重复n次,左右都是闭区间
    {m,}表示前置表达式至少重复m次

    正则表达式中的逻辑匹配

    逻辑匹配指的是,对字符串中的字符间的逻辑关系、位置关系、组别关系等进行匹配。逻辑匹配不匹配任何字符,也不匹配次数

    表达式 作用
    () 在正则表达式中()用来实现分组。括号中的表达式将作为一个整体看待,在获取匹配结果时,小括号包含的表达式所匹配到的字符串可以单独获取。如:表达式 "¥(\d+\.?\d*)" 在匹配 "$10.9,¥20.5" 时,匹配到的内容是:"¥20.5";单独获取括号范围匹配到的内容是:"20.5"。注意note:正则表达式中的()不匹配任何字符而仅作为分组,如果需要匹配字符串中的小括号,需要使用\(和\)
    ^ 与目标字符串开始的地方匹配,不匹配任何字符
    $ 与目标字符串结束的地方匹配,不匹配任何字符
    \b 匹配一个单词的边界,它要求它在匹配结果中所处位置的左右两边,其中一边是 "\w" 范围,另一边是 非"\w" 的范围。同样不匹配任何字符
    | 表示正则表达式之间的 "或" 关系,如'a|b',表示匹配a也行,匹配b也行

    正则表达式的高阶用法

    • 贪婪匹配和非贪婪匹配

    次数表达式在匹配过程中,默认总是尽可能多的匹配,即默认贪婪匹配。事实上,贪婪匹配并不适用于所有的情况。

    如,字符串'哈哈哈哈哈',若想通过正则表达式确定其最大重复单元,那么使用正则表达式 '(.+)\1+' 捕获分组可以得到'哈哈';但如果我们需要确定最小重复单元,就需要分组能够命中的字符串长度尽可能少,也就是使用非贪婪匹配
    在匹配次数表达式(?、 +、 *、{m, n})后再加上一个 "?" 号,可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不去匹配"
    因此,使用正则表达式 '(.+?)\1+' 或者 '(.{1,}?)\1+' 捕获分组可以得到最小重复单元'哈'

    • 分组的捕获值的引用

    "小括号包含的表达式所匹配到的字符串"--即分组的捕获值 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式可以引用前面的分组捕获值。引用方法是 "" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号
    如上面的非贪婪匹配提到的 '(.+?)\1+' 中 的\1表示的就是转义格式下的\1,从而实现对(.+?)捕获值的引用

    关于正则表达式,还可参考http://www.regexlab.com/zh/regref.htm


    python中的正则表达式

    python中的re库实现了正则表达式操作

    常用操作为search、findall和sub

    • re.search

    在字符串中寻找被pattern命中的部分,返回首个命中部分的re.Match object,未命中则返回None
    对于re.Match object,可以使用group()获取被整个pattern命中的字符串使用groups()获取被pattern中各个()分组所命中的字符串,以tuple形式

    例如:

    >>> pattern = 'i love (.+)'
    >>> s = 'xxx i love u'
    >>> res = re.search(pattern, s)
    >>> print(res)
    <re.Match object; span=(4, 12), match='i love u'>
    >>> res.group()
    'i love u'
    >>> res.groups()
    ('u',)

    • re.findall()

    Return a list of all non-overlapping不重叠的 matches in the string.
    If one or more capturing groups are present in the pattern 如果pattern里包含多个()分组, return
    a list of groups; this will be a list of tuples if the pattern has more than one group.

    Empty matches are included in the result.

    如果pattern中不含分组,则返回被整个pattern命中的所有结果的list
    如果pattern中包含分组,则返回被整个pattern命中的所有结果的分组tuple-list

    例如:

    # pattern中包含2个group,(\w+)和(\d{2}\.\d{2})
    >>> results = re.findall('title="(\w+)".*?<p class="pl">.*?(\d{2}\.\d{2}).*?</p>', content, re.S)
    >>> print(results)
    [('追风筝的人', '29.00'), ('小王子', '22.00'), ('围城', '19.00')]
    
    • re.sub

    re.sub(pattern, repl, string, count) 找到string中被整个patern命中的部分,使用repl替换,返回替换后的字符串
    例如:

    # (\w)\\1{2}的原型是(\w)\1{2},'\\1'是'\1'的转义,表示第一个分组匹配到的值
    >>> pattern = '(\w)\\1{2}'
    >>> s = 'xxx i love u'
    >>> res = re.sub(pattern, '', s)
    >>> res
    ' i love u'
    

    相关文章

      网友评论

          本文标题:python与正则表达式 2020-01-02(未经允许,禁止转

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