这两天在写爬虫程序,涉及英文文本处理,需要规范化英文标点符号的写法。正常情况下,英文句号「.」后面需要保证有且只有一个空格,但也有例外情况,比如「i.e.」、「e.g.」、「P.S.」这种。由于无法预测大小写,因此在正则表达式中使用了「标志位」flags,却死活不生效。

一开始,我的函数是这样写的:

1 def punctuate(s):
2 #----其余代码暂略
3 s = re.sub(' e. g. ', 'e.g.', s, re.I)
4 return s

代码的本意是:本来好好的「e.g.」,被函数前半断的代码错改成「e. g. 」之后,需要修复一下,将英文句号「.」后面的空格删掉。但这行 re.sub() 代码主要有2个问题:

  1. 「e. g.」前后不一定是空格,因此这样写的话,如果遇到「e. g.,」或是「(e. g. xxx」的情况就会被跳过。
  2. 英文的句号「.」未转义
  3. 标志位 re.I 不生效

前2个问题好解决。改进代码如下:

1 def punctuate(s):
2 #----其余代码暂略
3 s = re.sub('([^a-zA-Z]e\.) (g\.[^a-zA-Z])', '\g<1>\g<2>', s, re.I)
4 return s

规则是:「e. g.」之前或之后,必须有「非英文字母」的字符(包括空格),且「e.」和「g.」中间有一个空格,则将中间的空格删掉,且保留前后的「非英文字母」(\g<1>表示查找到的第1个括号内的文本,\g<2>表示第2个括号)。但标志位 re.I 的问题还是没解决。

后来翻到了「Python--详解Python中re.sub」这篇文章,才顿悟:re.sub() 函数有5个参数,我传入了4个参数,最后一个被认为是第4个参数,而不是第5个!多么低级的错误啊!

查阅「Python官方文档」可知,

re.sub(pattern, repl, string, count=0, flags=0)

我传入的第4个参数 re.I 会被当作是 count。因此,正确的姿势是明确写明「flags=re.I」。

整个标点符号规范化函数还包括其它的替换,完整代码如下:

 1 def punctuate(s):
2 s = re.sub('([,:;?!\.”\)])', '\g<1> ', s) #后加空格
3 s = re.sub('([“\(])', ' \g<1>', s) #前加空格
4 s = re.sub('([“\(]) ', '\g<1>', s) #后删空格
5 s = re.sub(' ([,:;?!\.”\)])', '\g<1>', s) #前删空格
6 s = re.sub('([,\.?!;\)]) ”', '\g<1>”', s) #闭引号前去空格
7 s = re.sub('\) ([,:;?!\.”])', ')\g<1>', s) #闭括号后去空格
8 s = re.sub('(\d)\. (\d)', '\g<1>.\g<2>', s) #小数点后去空格
9 s = re.sub(' +', ' ', s) #多空格改单空格
10 #拉丁加点缩写单词,点号后面去空格
11 s = re.sub('([^a-zA-Z]e\.) (g\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
12 s = re.sub('([^a-zA-Z]i\.) (e\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
13 s = re.sub('([^a-zA-Z]q\.) (v\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
14 s = re.sub('([^a-zA-Z]v\.) (s\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
15 s = re.sub('([^a-zA-Z]n\.) (b\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
16 s = re.sub('([^a-zA-Z]p\.) (s\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
17 s = re.sub('\. ,', '.,', s)
18 return s

多么痛的领悟!

Python正则表达式 re.sub()函数:标志位flags与参数个数问题的更多相关文章

  1. python学习道路(day4note)(函数,形参实参位置参数匿名参数,匿名函数,高阶函数,镶嵌函数)

    1.函数 2种编程方法 关键词面向对象:华山派 --->> 类----->class面向过程:少林派 -->> 过程--->def 函数式编程:逍遥派 --> ...

  2. 第11.3节 Python正则表达式搜索支持函数search、match、fullmatch、findall、finditer

    一. 概述 re模块的函数search.match.fullmatch.findall.finditer都是用于搜索文本中是否包含指定模式的串,函数的参数都是一样的,第一个参数是模式串.第二个是搜索文 ...

  3. Python中动态编译函数compile(source, filename, mode, ......)参数filename的作用是什么?

    动态编译函数compile调用语法如下: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) 其中的fi ...

  4. python中,print函数的sep和end参数

    print函数是我们经常使用的,但是它的sep和end参数或许对很多python使用者相对陌生,他们可以让我们的打印更具有个性化. 先来看下官方解释, sep:分割值与值,默认是一个空格 end:附件 ...

  5. js中函数调用时,对参数个数和类型没有要求

    因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java一样对其传入参数的类型进行定,也对传入参数的个数没有要求. js函数的参数与大多数其他语 ...

  6. 简介Python正则表达式

    一.概念 简单来说正则表达式是由一些普通字符(例如,a 到 z 之间的字母)和一些元字符组成,用来匹配和过滤一些字符串的一种逻辑公式. 二.正则表达式的一些基本规则 1.一些常用的元字符   ^  : ...

  7. 第11.25节 Python正则表达式编译re.compile及正则对象使用

    一. 引言 在<第11.2节 Python 正则表达式支持函数概览>介绍了re模块的主要函数,在<第11.3节 Python正则表达式搜索支持函数search.match.fullm ...

  8. Python正则表达式处理中的匹配对象是什么?

    老猿才开始学习正则表达式处理时,对于搜索返回的匹配对象这个名词不是很理解,因此在前阶段<第11.3节 Python正则表达式搜索支持函数search.match.fullmatch.findal ...

  9. python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义

    本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...

随机推荐

  1. 使用【QQ五笔的码表】转成【百度手机自定义码表】

    使用[QQ五笔码表]转成[百度手机自定义码表] QQ五笔码表先转成多多格式. 这里选用极点>>多多. 然后去掉空格. 转成GB.去掉没的字. 百度要的是这种格式. 现再用点讯工具转成 de ...

  2. Mono生命周期小实验

    今天在写代码的时候,遇到一个初始化顺序问题,于是做了一个实验,下面记录结果: 情景: 1.在 脚本A中实例化 一个预制体,该预制体挂有脚本B 2.在 脚本A中,获取实例化物体 身上的 脚本B,并且设置 ...

  3. Mysql 部署

    设置 path 环境变量 C:\mysql\mysql-5.7.17-winx64\bin; 创建C:\mysql\mysql-5.7.17-winx64\my.ini 内容如下 [mysql] # ...

  4. HashMap位运算你可知一二

    前置位运算知识 我们平时在写代码过程中用的位运算操作比较少,因为我们更关注于可读性而不是性能,如果为了性能而使用较多的位运算,我想我们的同事会疯掉.但在框架里位运算却非常常见,因为框架的性能是我们关注 ...

  5. 简介&目录

    欢迎来到 MK 的博客鸭~ 这里会被我用来发一些OI算法.数据结构的学习笔记,各种游记和其他的一些内容,希望大家多多关照! ε≡٩(๑>₃<)۶ 然后目录就也放这里⑧:

  6. 小程序mpvue中flyio的使用方法

    Fly.js 一个基于Promise的.强大的.支持多种JavaScript运行时的http请求库. 有了它,您可以使用一份http请求代码在浏览器.微信小程序.Weex.Node.React Nat ...

  7. 14_Web服务器-并发服务器

    1.服务器概述 1.硬件服务器(IBM,HP): 主机 集群 2.软件服务器(HTTPserver Django flask): 网络服务器,在后端提供网络功能逻辑处理数据处理的程序或者架构等 3.服 ...

  8. 利用ANSI转义序列在控制台输出彩色文字

    说明:无论什么语言,只要你的终端能够解释ANSI转义序列(大多数的类unix终端仿真器都能够解释ANSI转义序列,win32控制台则不支持),就能够使用ANSI转义序列输出颜色.这个功能看似鸡肋,但只 ...

  9. 如何让Web程序在点击按钮后出现如执行批处理程序般的效果

    在cli程序中,输入命令得到连续的输出已经是一种进度而美观的页面交互形式,好比下图: 而web程序里也有类似的场景,比如执行一个耗时任务,除了显示出等待图标外,用户还希望把执行的状态及时显示出来.如下 ...

  10. [oracle/sql]关于清除重复,not in方案和not exists方案的对比

    有这样一张表: CREATE TABLE tb_sc ( id NUMBER not null primary key, studentid int not null, courseid int no ...