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)
[]
>>>

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

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

9. 将Unicode文本标准化

>>> s1 = 'Spicy Jalape\u00f1o'
>>> s2 = 'Spicy Jalapen\u0303o'
>>> 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 Jalape\xf1o'
>>> t3 = unicodedata.normalize('NFD', s1)
>>> t4 = unicodedata.normalize('NFD', s2)
>>> t3 == t4
True
>>> print(ascii(t3))
'Spicy Jalapen\u0303o'
>>>

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

10. 在正则式中使用Unicode

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

混合使用Unicode和正则表达式通常会让你抓狂。 如果你真的打算这样做的话,最好考虑下安装第三方正则式库, 它们会为Unicode的大小写转换和其他大量有趣特性提供全面的支持,包括模糊匹配。

python3: 字符串和文本(2)的更多相关文章

  1. [转]python3字符串与文本处理

    转自:python3字符串与文本处理 阅读目录 1.针对任意多的分隔符拆分字符串 2.在字符串的开头或结尾处做文本匹配 3.利用shell通配符做字符串匹配 4.文本模式的匹配和查找 5.查找和替换文 ...

  2. python3字符串与文本处理

    每个程序都回涉及到文本处理,如拆分字符串.搜索.替换.词法分析等.许多任务都可以通过内建的字符串方法来轻松解决,但更复杂的操作就需要正则表达式来解决. 1.针对任意多的分隔符拆分字符串 In [1]: ...

  3. python3: 字符串和文本(4)

    16. 以指定列宽格式化字符串[textwrap] https://docs.python.org/3.6/library/textwrap.html#textwrap.TextWrapper 假如你 ...

  4. python3: 字符串和文本(3)

    11. 删除字符串中不需要的字符  strip() 方法能用于删除开始或结尾的字符: lstrip() 和 rstrip() 分别从左和从右执行删除操作 >>> s = ' hell ...

  5. python3: 字符串和文本

    1. 分割字符串-使用多个界定符[re.split()] >>> line = 'asdf fjdk; afed, fjek,asdf, foo' >>> impo ...

  6. Python3-Cookbook总结 - 第二章:字符串和文本

    第二章:字符串和文本 几乎所有有用的程序都会涉及到某些文本处理,不管是解析数据还是产生输出. 这一章将重点关注文本的操作处理,比如提取字符串,搜索,替换以及解析等. 大部分的问题都能简单的调用字符串的 ...

  7. Python3 批量替换文本内容

    Python3 批量替换文本内容 示例: # coding:utf8 import os; def reset(): i = 0 path = r"H:\asDemo\workdemo\aw ...

  8. 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制

    过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...

  9. python3字符串

    Python3 字符串 Python字符串运算符 + 字符串连接 a + b 输出结果: HelloPython * 重复输出字符串 a*2 输出结果:HelloHello [] 通过索引获取字符串中 ...

随机推荐

  1. c#基础学习(0724)之可变参数、ref和out

    params可变参数,无论有几个参数,必须出现在参数列表的最后,可以为可变参数直接传递一个对应类型的数组 #region 可变参数 //1.如果方法有多个参数,可变参数可以作为最后一个参数 //2.可 ...

  2. sql中非存储过程定义参数并使用

    DECLARE @dt datetime SET @dt=GETDATE()--1.短日期格式:yyyy-m-d SELECT REPLACE(CONVERT(varchar(10),@dt,120) ...

  3. GetHashCode方法学习

    GetHashCode方法我的理解是做两个对象的比较,每个对象,不管是值类型还是应用类型都提供这个基本函数,都可以去重写它.GetHashTable通常用于HashTable.List<> ...

  4. 初学nodejs之安装Express中遇到的问题: error: option `-v, --view <engine>' argument missing

    Windows安装下载nodejs地址:http://nodejs.org/download/ node -v 查看安装版本,输出版本即安装成功 之前学习了nodejs的基础,今天安装Express框 ...

  5. 单点登录在asp.net中的简单实现

    系统的基本架构 我们假设一个系统System包含Service客户服务中心.Shop网上购物中心和Office网上办公中心三个独立的网站.Service管理客户的资料,登录和注销过程.不论客户访问Sy ...

  6. Jquery Easy UI初步学习(二)datagrid的使用

    第一篇学的是做一个管理的外框,接着就是数据datagrid绑定了,这里我用asp.net mvc3来做的,主要就是熟悉属性.方法. 打开easyui的demo 就可以看到如下一段代码: 和上篇一样cl ...

  7. 关于Comparator和Comparable的理解

    我们都知道,实现Comparator和Comparable这两个接口,可以实现对对象比较大小.那这个两个又有什么区别呢? comparator 1.接口类在java.util包里面,实现接口时需要导入 ...

  8. vue-router 实现导航守卫(路由卫士)

    路由跳转前做一些验证,比如登录验证,是网站中的普遍需求. 对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫(navigation-guards). 导航守卫 ...

  9. L1 Cache, L2 Cache读取命中率与时钟周期计算

    CPU在Cache中找到有用的数据被称为命中,当Cache中没有CPU所需的数据时(这时称为未命中),CPU才访问内存.从理论上讲,在一颗拥有2级Cache的CPU中,读取L1 Cache的命中率为8 ...

  10. Android设备网络、屏幕尺寸、SD卡、本地IP、存储空间等信息获取工具类

    Android设备网络.屏幕尺寸.SD卡.本地IP.存储空间.服务.进程.应用包名等信息获取的整合工具类. package com.qiyu.ddb.util; import android.anno ...