精通正则表达式学习记录 第二章 入门示例扩展
用环视功能为数值添加逗号
为了更好地显示大的数值,可以每三个数值加一个逗号显示如298444215
显示为298,444,215
。要用正则表达式来匹配这样的文本,需要使用新特性“环视”。
环视结构:不匹配任何字符,只匹配文本中特定的位置,这一点与单词分界符\b
锚点^
和$
相似。但是,环视比它们更加通用。
一种类型的环视叫顺序环视,它顺序查看文本,尝试匹配子表达式,如果能够匹配,就返回匹配成功信息。
肯定型环视:用特殊的序列(?=...)
来表示,例如(?=\d)
,它表示如果当前位置右边的字符是数字则匹配成功。
逆序环视:它逆序(从右到左)查看文本。用特殊的序列(?<=...)
表示,例如(?<=\d)
表示如果当前位置的左边有一位数字则匹配成功。
环视不会“占用”字符
一些例子:
正则表达式Jeffrey
匹配文本串...by Jeffery Friedl.
中的对应单词。但同样的正则表达式如果使用环视,即(?=Jeffery)
,则匹配标记的位置。
正则表达式(?=Jeffery)Jeff
精确匹配Jeff
,而祛除了ery
。该正则表达式等价于表达式Jeff(?=ery)
。注意环视用来匹配位置而不占用字符。
在讲解如何给大数值加逗号之前,先用一个简单的例子来说明环视是如何匹配位置并在某位置插入字符的。
假设我们要实现:将文本Jeffs
替换为Jeff's
。
最简单的是使用s/Jeffs/Jeff's/g
,但是更好地方法是使用单词界定符s/\bJeffs\b/Jeff's/g
。
还可以使用更复杂的例子:s/\b(Jeff)(s)\b/$1'$2/g
。但是这个方法更复杂。当使用环视时可以写作:s/\bJeff(?=s\b)/Jeff'/g
。只有当s\b
在Jeff
匹配之后的位置时,整个正则表达式才能够匹配。但是,因为s\b
只是顺序环视子表达式的一部分,它所匹配的s
不属于最终匹配的文本。注意Jeff
确定匹配文本,而顺序环视只是“选择”一个位置。
还有两个只用环视来确定位置的写法如下:
s/(?<=\bJeff)(?=s\b)/'/g
s/(?=s\b)(?<=\bJeff)/'/g
都可以实现插入'
。上面的例子匹配这样一个位置:该位置位于Jeff
的右边且位于s
的左边。然后在该位置放入'
。这样就完成了我们要实现的功能。
回到逗号的例子
要解决插入逗号的问题,应该找满足下面两个条件的位置:
- 它的左边有数字,这就是
(?<=\d)
。 - 它的右边数字的个数正好是3的倍数,
(?=(\d\d\d)+$)
来实现。
完整的程序是:
$pop =~ s/(?<=\d)(?=(\d\d\d)+$)/'/g;
print "The US population is $pop\n";
这就可以输出以逗号分割的美国人口数。
单词分界符和否定环视
如果用上述正则表达式(s/(?<=\d)(?=(\d\d\d)+$)/'/g;
)匹配文本The population of 298444215 is growing
;
是匹配不到的,因为数字不是句子的末尾。
这里为了处理这种情况需要用单词分界符来界定数值。可以用\b
来替换$
。
单词分界符的意思是:在此位置的一侧是单词(例如数字),另一侧不是(例如行的末尾,或者数字后面的空格)。
这个“一侧如此这般,另一侧如此那般”与例子Jeffs
很类似。
- 肯定顺序环视(
(?=...)
)和肯定逆序环视((?<=...)
):它们成功的条件是子表达式在这些位置能够匹配。 - 否定逆序环视(
(?<!...)
)和否定顺序环视((?!...)
)。
所以,如果单词分界符的意思是:一侧是\w
另一侧不是\w
,我们就能用(?=\w)(?<!=\w)
来表示单词起始分界符。用(?!\w)(?<=\w)
匹配单词的结束分界符。把两者结合起来等价于((?<!\w)(?=\w)|(?<=\w)(?!\w))
就等价于\b
。在实践中,直接使用\b
更简便,效率也更高。
所以上述逗号插入问题可以写成下面的正则:
$text =~ s/(?<=\d)(?=(\d\d\d)+(?!\d))/'/g;
但是上面的表达式会和...the 1970s...
匹配。实际上,我们根本不希望这里的正则表达式能够匹配... in 1970...
。所以,我们必须知道期望用正则表达式处理的文本,以及开发的程序适合解决什么样的问题(如果数据包含年份信息,这个正则表达式就可能不适合)。
不通过逆序环视添加逗号
不用逆序环视解决加逗号的问题:$text =~ s/(\d)((\d\d\d)+(?!\d))/$1,/g;
是否可以连顺序环视都不用呢?即下面的例子是否可以:$text =~ s/(\d)((\d\d\d)+\b)/$1,$2/g;
。答案是不可以,会得到"281,421906"的字符串。这是因为(\d\d\d)+
匹配的数字属于最终匹配文本,所以不能作为“未匹配的”部分,供/g
的下一次匹配迭代使用。
精通正则表达式学习记录 第二章 入门示例扩展相关推荐
- 精通正则表达式学习记录 第一章 正则表达式入门
一个例子:检索某台服务器上的页面重复的单词如"The the".可能会有很多特俗的要求比如: 能检查多个文件 能跨行查找 能进行大小写区分查找 能找出用HTML tag分割的重复单 ...
- 《SysML精粹》学习记录--第二章
<SysML精粹>学习记录 第二章:系统建模语言概览 SysML介绍 SysML与UML SysML图概览 SysML通用图 小结 第二章:系统建模语言概览 SysML介绍 SysML ...
- Solidity学习记录——第二章
Solidity学习记录 第一章 创建生产僵尸的工厂 第二章 设置僵尸的攻击功能 第三章 编写DAPP所需的基础理论 第四章 完善僵尸功能 第五章 ERC721 标准和加密资产 文章目录 Solidi ...
- C语言深度剖析书籍学习记录 第二章 符号
\ 连接符号,// \ 可以把下一行也注释调 编译器 删除注释时,会使用空格进行替代
- 编译原理语法分析_斯坦福大学《编译原理》学习记录 - 第二章:语法分析器
05-01: Introduction to Parsing 语法分析 parser的作用: 05-02: Context Free Grammars 上下文无关文法 CFG(上下文无关文法)回答了一 ...
- 【洛谷】洛谷深基学习记录 第二章 顺序结构程序设计
一.知识积累 1.自动类型转换 #include<iostream> using anmespace std; int main(){int a=1,b=2; /*int指的是数据类型中的 ...
- Shell脚本学习指南 - 第二章入门篇
shell脚本的第一行#! #! /bin/awk -f 内核会扫描文件开头的#!后面内容,跳过所有空白符号,寻求可以用来执行程序的解释器的full path和option(option后面的空格会识 ...
- [go学习笔记.第二章] 2.go语言的开发工具以及安装和配置SDK
一.工具介绍: 1.Visual Studio Code 一个运行于Mac,Windows,和linux上的,默认提供Go语言的语法高亮的IED,可以安装Go语言插件,还可以支持智能提示,编译运行等功 ...
- 小吴的《机器学习 周志华》学习笔记 第二章 模型评估与选择
小吴的<机器学习 周志华>学习笔记 第二章 模型评估与选择 上一周我们介绍了第一章的基础概念,这一次将带来第二章的前三节.后面的2.4 比较检验与2.5 偏差与方差,涉及概率论与数理统计概 ...
- 《Go语言圣经》学习笔记 第二章 程序结构
Go语言圣经学习笔记 第二章 程序结构 目录 命名 声明 变量 赋值 类型 包和文件 作用域 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. Go语言小白学习笔记,几乎是书上的内 ...
最新文章
- Hadoop集群搭建(二:集群主机间免密登录配置)
- IDEA JNI配置
- RedHat7/Centos7 搭建NFS服务器
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
- DCMTK:类DcmPersonName的测试程序
- 算法学习之循环结构程序设计
- 【纠错记录】本地FTP服务器无法被外部连接
- jvm gc垃圾回收机制和参数说明amp;amp;Java JVM 垃圾回收(GC 在什么时候,对什么东西,做了什么事情)
- word打开老是配置进度_word怎么转pdf?两个值得学习的高效转换法
- opencv图像分析与处理(14)- 图像压缩基础知识
- 2021SC@SDUSC Zxing开源代码(十一)Data Matrix二维码(四)
- mongoose时间自动转化为格林尼治标准时间的解决方案
- java ckfinder_java 使用ckfinder
- 按键精灵电脑版对接百度ai,告别字库(文字识别篇)
- 计算显卡算力测试软件,380显卡算力多少
- 计算机无法打开pdf文件格式,pdf格式的文件打不开 [电脑打不开pdf格式文件怎么回事]...
- google colab使用入门
- js中获取只包含一种字符的最长非空子字符串的长度
- 彻底解密C++宽字符
- 计算机启动后桌面图标都没有了,我的电脑开机后桌面上的图标都没了怎么办?...
热门文章
- 微软报表工具服务器版本,Report Builder 3.0
- 什么水果有利于饭后消化?
- 漫画 | 阿姨,我不想努力了~
- MyBatis 大于小于符号表示
- VISIO同时选中多条线
- adb连接手机工具_adb命令——连接手机
- 方舟生存进化手机版服务器无限琥珀,方舟生存进化无限琥珀
- 斯人已去长风存 谈谈 CyanogenMod 的前身今世
- [SAP ABAP开发技术总结]增强Enhancement
- (转)金蝶KIS迷你版、标准版在查询数量金额明细账时提示“发生未知错误,系统当前操作被取消,请与金蝶公司联系”...