1.使用正则表达式修改文本

1.使用正则表达式修改文本

正则表达式的功能不只有查询,还可以对文本进行修改,例如替换

$var=~m/regex/i                             
$var=~s/regex/replacement/i

Replacement两侧的斜杠相当于双引号,也就是说replacement中可以有$1,$2这样的变量来代表前面匹配到的内容

$var=~s/regex/replacement/可以改变$var中的文本,如果没有匹配成功,就不会有文本的替换

$var=Jeff frield;
$var=~s/Jeff/Jeffery/;
$var=Jeffery frield

可是如果在运行$var=~s/Jeff/Jeffery/一次,就会得到:

$var=Jefferyery fried;

因为Jeff始终被匹配,所以替换始终会发生。

要避免这样的情况,我们必须要把匹配条件说的再具体一些。

匹配的是Jeff这个单词,而不是这四个字母,所以我们用:

$var=~s/\bJeff\b/Jeffery/

这样子第二次运行$var=~s/\bJeff\b/Jeffery/就不会再改变文本了

1.1例子一公函生成器

设想有一个公函系统,它包含很多公函魔板,其中一些标记,对每一封具体的公函来说,标记部分的值都有所不同

例如:

尊敬的=FIRST=,

恭喜您!获得了=TRINKET=!完全免费!您还想为=FAMILY=家获得更多的=TRINKEY=吗?告诉你=FULL=,你可以的!

然后设置三个变量:

$given="王";
$family="小明";
$prize="10000克拉的钻石";

然后我们就可以为语句的模板填写内容:

$letter=~s/=FIRST=/$family/g;
$letter=~s/=FAMILY=/$given/g;
$letter=~s/=FULL=/$given $family/g;
$letter=~s/=TRINKET=/价值连城$prize/g;

g是全局替换的修饰符,他告诉s///在一次匹配替换成功以后继续下一次,直到匹配不成功为止,从而达到全部相关文本都被替换的效果

结果:

尊敬的 小明,

恭喜您!获得了 价值连城10000克拉的钻石!完全免费!您还想为王家获得更多的价值连城10000克拉的钻石吗?告诉你王小明,你可以的!

1.2 例子二修整数字格式

有时候因为计算机内部表示浮点的原理,输出来的数字是9.05000000372272,可是我们其实只需要保留小数点后三位就可以了

要求就是:保留小数点后两位,如果第三位不为0,也要保留,例如12.3750000000392会变成12.375,37.500会变成37.50.

$num=~s/(\.\d\d[1-9]?)\d*/$1/;

用环视功能为数值添加逗号

大的数值,为了方便读懂,通常在其间加入逗号。

Print "the US population is $pop\n";

会输出the US population is 298444215,但298,444,215会更加顺眼。

我们应该从数字的右边开始,每次数三个数字如果左边还有数字,就加入一个逗号。

这是直观的想法,但是正则表达式是从左到右去处理文本的。

逗号应该加在”左边有数字,右边数字的个数正好是3的倍数的位置“。

对于这样的任务,我们用环视功能来实现。

环视结构不匹配任何字符,只匹配文本中特定的位置。这个特性其实我们前面已经见过很多次,例如\b、^、$等,都是匹配一个位置,但环视比它们更加通用,因为它匹配的位置是你自己定义的。

顺序环视:从左到右查看文本,尝试匹配正则表达式。肯定型顺序环视用(?=……)来表示,例如(?=\d),表示如果当前位置右边的字符是数字则匹配成功

逆序环视:从右到左查看文本,尝试匹配正则表达式。肯定型逆序环视用(?<=……)来表示,例如(?<=\d),表示如果当前位置左边字符是数字则匹配成功(也就是紧跟在数字后面的位置)。

环视正则表达式在匹配的时候不会“占用”字符,只是匹配位置。

用Jeffery匹配by Jeffery friedl,匹配到是Jeffery这几个字符之前的位置

把环视结构和真正匹配的字符结合起来使用,我们能匹配到更加精准的内容,例如:

(?=Jeffery)Jeff

能匹配到by Jeffery friedl

不能匹配by Jefferson

(?=Jeffery)Jeff ;Jeff(?=ery)

Jeff(?=Jeffery)不能够匹配以上例子,而是匹配后面紧跟Jeffery的Jeff,例如JeffJeffery

1.3例子三effs=》Jeff’s

把Jeffs换成Jeff’s

s/Jeffs/Jeff’s/
s/\bJeffs\b/Jeff’ s/
s/\b(Jeff)(s)\b/$1’$2/
s/\bJeff(?=s\b)/Jeff’/

环视只是匹配一个位置,它的好处是容许我们在匹配Jeff前先检查整个Jeffs

s/(?<=\bJeff)(?=s\b)/’/
s/(?=s\b)(?<=\bJeff)/’/

用顺序环视和逆序环视找到了一个精确的位置,因为找的只是位置,所以条件循序调换了也没有影响。

1.4例子四回到逗号

“左边有数字,右边数字的个数正好是3的倍数”。

第一个要求用逆序环视就能够满足,左边有数字,(?<=\d)

第二个要求:3位数字可以表示成\d\d\d,然后可以用(\d\d\d)+表示3的若干倍

最后再加上$来确保这些数字后面不存在其他字符,以保证这样的结果“正好”在最后3位数字之后结束

$pop=~s/(?<=\d)(?=(\d\d\d)+$)/,/g;
Print"The US population is $pop\n";

298,444,215

试想,如果不加$,会有什么后果?

$pop=~s/(?<=\d)(?=(\d\d\d)+)/,/g;

2,9,8,4,4,4,215

而且这里括住\d\d\d的括号,其实我们只是用来使得+可以作用于这个括号,并没有使用它的捕获功能,所以可以写成非捕获型括号:(?:......)

$pop=~s/(?<=\d)(?=(?:\d\d\d)+$)/,/g;

否定环视

现在,我们又希望把这个插入逗号的正则表达式应用到很长的字符串汇中,例如

$text="The population of 299444215 is growing"

这样子s/(?<=\d)(?=(\d\d\d)+$)/,/g;就不管用了,因为数字之后不是结尾,所以匹配不成功

解决方法:可以把$换成\b,尽管\b被称为单词分隔符,但是对于perl来说,匹配单词的\w是[a-zA-Z0-9],把数字也包括进去了,所以这是广义的单词

注意到这里,\b的意思就是,在此位置的一侧是单词,另外一侧不是

环视也有相关的概念,前面我们说的(?=)(?<=)都叫做肯定顺序环视和肯定逆序环视。因为他们成功的条件是子表达式在这些位置能够匹配

另外还有否定顺序环视(?!)和否定逆序环视(?<!),他们成功条件是子表达式无法匹配

类型 正则表达式 匹配成功的条件
肯定顺序环视 (?=) 子表达式能够匹配右侧文本
肯定逆序环视 (?<=) 子表达式能够匹配左侧文本
否定顺序环视 (?!) 子表达式不能够匹配右侧文本
否定逆序环视 (? 子表达式不能够匹配左侧文本

这样,其实\b就是(?<!\w)(?=\w)|(?<=\w)(?!\w)

s/(?<=\d)(?=(\d\d\d)+(?!\d)/,/g;

不是所有的宿主语言都支持逆序环视

那么我们可以这样子写,这样就没有用到逆序环视

s/(\d)(?=(\d\d\d)+$)/$1,/g;

如果连顺序环视都不用呢?

s/(\d)((\d\d\d)+\b)/$1,$2/g;

可以吗?

答案是不可以,结果是298,444215

因为g这个修饰符规定,下一次匹配是在这一次匹配的终点开始的。但是在第一次匹配时,(\d\d\d)+\b已经匹配了444215,所以g的下一次匹配开始是在5的后面

解决方法是在perl中加个while循环,重复匹配,而不是迭代匹配

2.正则表达式使用注意事项

在某种特定的宿主语言或工具软件中使用正则表达式时,主要有3个问题需要注意

1.支持的元字符,以及这些元字符的意义,这通常称为正则表达式的“流派”

2.正则表达式与语言工具的“交互方式”。譬如如何进行正则表达式的操作,容许进行哪些操作,以及这些操作的目标文本类型

3.正则表达式引擎如何将表达式应用到文本

由于正则表达式的漫长的发展史,众多程序员,新的程序又形成自己的流派,所以就成了巨大的迷局。

直到1986年,POSIX(一系列标准)诞生,它是标准化的尝试,试图把缠绕不清的正则表达式各个流派标准化,用同一套规则来实现正则表达式。它把各种常见的流派分为两大类:

Basic Regular Expressions(BREs)和Extended Regular Expressions(EREs)

POSIX程序必须支持其中任意一种

perl正则表达式第二周笔记的更多相关文章

  1. perl正则表达式第一周笔记

    正则表达式基础 ^ 行首标志 $ 行末标志 如^cat即一整行只有cat这个单词,^则是一个空行 [  ] 字符组,用来匹配若干字符之一 如gr[ae]y,即grey或者gray - 在字符组内部,字 ...

  2. 《Linux内核分析》第二周笔记 操作系统是如何工作的

    操作系统是如何工作的 一.函数调用堆栈 1.三个法宝 计算机是如何工作的?(总结)——三个法宝(存储程序计算机.函数调用堆栈.中断机制) 1)存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ...

  3. 20165326 java第二周学习笔记

    学习笔记 一.理论学习 基本数据类型与数组 标识符的第一个字符不能是数字:标识符不能为关键字. 基本数据类型多数与c语言相同.重点如下: 1.逻辑类型boolean赋值true/false 2.浮点数 ...

  4. 《Linux内核分析》第二周学习笔记

    <Linux内核分析>第二周学习笔记 操作系统是如何工作的 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  5. Linux内核分析第二周学习笔记

    linux内核分析第二周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  6. Java学习第二周学习笔记

    20145307<Java程序设计>第二周学习总结 教材学习内容总结 Java语言中的很多基本语法都和C语言类似,以下Java中的基本语法 标识符 标识符是程序中自定义的一些名称. 由26 ...

  7. 20145231第二周Java学习笔记

    20145231 <Java程序设计>第2周学习总结 教材学习内容总结 本周的学习采用的依然是先看课本,再看视频,然后实践敲代码,最后根据学习笔记总结完成博客. 第三章:基础语法 知识点比 ...

  8. 红帽学习笔记[RHCSA] 第二周

    目录 红帽学习笔记[RHCSA]第二周 环境 第七课[网络配置相关] 在Vmware中添加网卡 将网卡添加到虚拟机上 关于网卡命名规则 配置网络 网络配置命令总结 更改hostname 关于SSH的一 ...

  9. 《Machine Learning》系列学习笔记之第二周

    第二周 第一部分 Multivariate Linear Regression Multiple Features Note: [7:25 - θT is a 1 by (n+1) matrix an ...

随机推荐

  1. microstrip patch antenna

    微带天线有很多优点,低成本,易于集成,加工简单,缺点有:效率低.功率容易低.高Q值 ,可能存在表面波,极化效果差,弱电扫性能.带宽窄.微带线的金属厚度t远远小于波长(t << λ0 ,自由 ...

  2. C#.net 中 修饰符 详解 (来自MSDN)

    自己理解的不够深刻,无奈基础较差!记上一笔,记忆深刻些,哈哈…… 1. 访问修饰符 public 同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员. private 只有同一 ...

  3. python中如何用dis模块来查看py的汇编代码?

    之前测试不成功,用导入dis的方式. 但如何在命令行里加入 -m dis,就会OK啦. python -m dis test.py #coding: utf8 x = [1, 2, 3] for i ...

  4. Convert and Cast for Date and Money format.

    SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '') The below script removes the TAB(Horozonta ...

  5. mysql 导入导出的几个常用参数

    导出命令: mysqldump -t --skip-extended-insert -utest -p testdb tableA > testdb_tableA.sql 参数说明: -t: 仅 ...

  6. 主机无法访问虚拟机的httpd服务

    症状:虚拟机装的centos6.3 通过桥接的方式与主机连接 虚拟机通过yum安装httpd服务 在主机浏览器中输入 虚拟机ip  无法访问虚拟机Apache 虚拟机和主机可以相互ping通 解决:关 ...

  7. 解决“Xlib.h not found when building graphviz on Mac OS X 10.8”错误

    After installing XQuartz you may add a symlink to your X11 installation folder by just entering (安装X ...

  8. CentOS7.0安装Nginx

    安装Nginx yum install nginx 正常情况下必定是: 已加载插件:fastestmirror, langpacks base | :: docker-main | :: extras ...

  9. Android实现登录小demo

    安卓,在小编实习之前的那段岁月里面,小编都没有玩儿过,如果说玩儿过,那就是安卓手机了,咳咳,敲登录的时候有种特别久违的熟悉,这种熟悉的感觉就和当时敲机房收费系统一样,那叫一个艰难啊,不过小编相信,在小 ...

  10. 微信跳转之WAP跳转微信公众号关注页面链接weixin://dl/business/?ticket=

    本文整理了部分微信 URL Schemes,经过本人测试,所有url在微信 6.3.22 版本下都可正常工作.大家可以在 Safari 中打开链接进行尝试.(部分链接仅允许在微信内部浏览器中打开,已用 ...