• python3: 字符串和文本(2)


    6. 字符串忽略大小写的搜索替换

    >>> text = 'UPPER PYTHON, lower python, Mixed Python'
    >>> re.findall('python', text, flags=re.IGNORECASE)
    ['PYTHON', 'python', 'Python']
    >>> re.sub('python', 'snake', text, flags=re.IGNORECASE)
    'UPPER snake, lower snake, Mixed snake'
    >>>

    7.最短匹配(?)

    Q: 你正在试着用正则表达式匹配某个文本模式,但是它找到的是模式的最长可能匹配。 而你想修改它变成查找最短的可能匹配。

    S:这个问题一般出现在需要匹配一对分隔符之间的文本的时候(比如引号包含的字符串)。 为了说明清楚,考虑如下的例子:模式 r'"(.*)"' 的意图是匹配被双引号包含的文本。(.)匹配除了换行外的任何字符

    >>> str_pat = re.compile(r'"(.*)"')
    >>> text1 = 'Computer says "no."'
    >>> str_pat.findall(text1)
    ['no.']
    >>> text2 = 'Computer says "no." Phone says "yes."'
    >>> str_pat.findall(text2)
    ['no." Phone says "yes.']

    第二个例子中搜索 text2 的时候返回结果并不是我们想要的。

    为了修正这个问题,可以在模式中的*操作符后面加上?修饰符,就像这样:

    >>> str_pat = re.compile(r'"(.*?)"')
    >>> str_pat.findall(text2)
    ['no.', 'yes.']
    >>>

    通过在 * 或者 + 这样的操作符后面添加一个 ? 可以强制匹配算法改成寻找最短的可能匹配。

      8. 多行匹配模式

    Q: 你正在试着使用正则表达式去匹配一大块的文本,而你需要跨越多行去匹配。

    S:这个问题很典型的出现在当你用点(.)去匹配任意字符的时候,忘记了点(.)不能匹配换行符的事实。 比如,假设你想试着去匹配C语言分割的注释:

    >>> comment = re.compile(r'/*(.*?)*/')
    >>> text1 = '/* this is a comment */'
    >>> text2 = '''/* this is a
    ... multiline comment */
    ... '''
    >>>
    >>> comment.findall(text1)
    [' this is a comment ']
    >>> comment.findall(text2)
    []
    >>>

    为了修正这个问题,你可以修改模式字符串,增加对换行的支持。比如: 

    #(?:.|
    ) 指定了一个非捕获组 (也就是它定义了一个仅仅用来做匹配,而不能通过单独捕获或者编号的组)
    >>> comment = re.compile(r'/*((?:.| )*?)*/') >>> comment.findall(text2) [' this is a multiline comment '] >>>

    (?:x) 

    匹配 'x' 但是不记住匹配项。这种叫作非捕获括号,使得你能够定义为与正则表达式运算符一起使用的子表达式。来看示例表达式 /(?:foo){1,2}/。如果表达式是 /foo{1,2}/,{1,2}将只对 ‘foo’ 的最后一个字符 ’o‘ 生效。如果使用非捕获括号,则{1,2}会匹配整个 ‘foo’ 单词。

     re.compile() 函数接受一个标志参数叫 re.DOTALL ,在这里非常有用。 它可以让正则表达式中的点(.)匹配包括换行符在内的任意字符。比如:

    >>> comment = re.compile(r'/*(.*?)*/', re.DOTALL)
    >>> comment.findall(text2)
    [' this is a
     multiline comment ']

    9. 将Unicode文本标准化

    >>> s1 = 'Spicy Jalapeu00f1o'
    >>> s2 = 'Spicy Jalapenu0303o'
    >>> s1
    'Spicy Jalapeño'
    >>> s2
    'Spicy Jalapeño'
    >>> s1 == s2
    False
    >>> len(s1)
    14
    >>> len(s2)
    15
    
    
    import unicodedata
    >>> t1 = unicodedata.normalize('NFC', s1)
    >>> t2 = unicodedata.normalize('NFC', s2)
    >>> t1 == t2
    True
    >>> print(ascii(t1))
    'Spicy Jalapexf1o'
    >>> t3 = unicodedata.normalize('NFD', s1)
    >>> t4 = unicodedata.normalize('NFD', s2)
    >>> t3 == t4
    True
    >>> print(ascii(t3))
    'Spicy Jalapenu0303o'
    >>>

    NFC表示字符应该是整体组成(比如可能的话就使用单一编码),而NFD表示字符应该分解为多个组合字符表示。Python同样支持扩展的标准化形式NFKC和NFKD

     10. 在正则式中使用Unicode

    re 模块已经对一些Unicode字符类有了基本的支持。 比如, \d 已经匹配任意的unicode数字字符了

    混合使用Unicode和正则表达式通常会让你抓狂。 如果你真的打算这样做的话,最好考虑下安装第三方正则式库, 它们会为Unicode的大小写转换和其他大量有趣特性提供全面的支持,包括模糊匹配。
  • 相关阅读:
    软件定义网络笔记(PART 1)
    软件架构-可视化
    nginx反向代理配置去除前缀
    年轻就该多尝试,教你20小时Get一项新技能
    LNMP架构部署(附:部署Discuz社区论坛Web应用)
    高级开发进阶:第一章:总篇
    pip和conda添加和删除镜像源
    Micro-PaaS(Docker+K8S)
    云平台概述
    1、Docker学习笔记
  • 原文地址:https://www.cnblogs.com/xiyuan2016/p/10335401.html
Copyright © 2020-2023  润新知