正则表达式学习笔记(二)捕获与环视

我们接着上面的笔记学习。我们今天的内容是捕获,后向引用和环视功能(正向,反向)。

在开始之前,有一些对于上一章博客的补充说明。上一章博客我们讲了元字符以及它的作用(用于匹配),但是有一些初学者容易懵逼的点之前没有说明,现在补充在这里。

1. 有些元字符代表在不同的语境下面代表不同的意思。

典型的有^和-,众所周知,^是锚点,匹配一个行的开头,但是如果在标记括号中,它代表的是反选,[^a]表示匹配一个不是a的字符,与[a]的意思相反。

对于-,在一般语境下面平平无奇,但是在标记括号[]中,在两个数字或者两个字母中间的时候,满足这两个条件,-语义发生变化,成为范围符号。比如,一般语境下面,-匹配-,在[]中,[1-3]和[a-z]分别匹配1到3和所有的小写字母。但是请注意,一定是满足既在标记括号中,又在字母或者数字中间,-才会是范围符号,如果[-az]就仅仅是匹配-或者a或者b了。

2. 正则表达式中,匹配的含义。

按照初学者(包括楼主)的理解,匹配就是匹配某个字符,如果找到了某个目标字符,我们就算匹配成功。诚然,这也是传统意义上面的字符查找,但是正则表达式作为一种强大的工具,匹配的含义远远大于传统意义,正则表达式可以匹配某个位置。如果对这一点感到疑惑,请想想锚点,无论是匹配行开头还是行结尾,锚点永远匹配的是一个位置而非某个字符。

3. 正则表达式有不同的流派。

作为一种强大的工具,很多语言对正则表达式都提供了良好的支持,比如Perl,Python,C#,Java甚至Notepad++等,但是每种语言对于正则表达式的支持又有些微的差别,有可能会出现要表达同样的语义,在不同的流派下面需要不同的句子,但是请不要担心,尽管选择你喜欢的,熟悉的工具来练习正则表达式吧,在你成为一个大师之前,你遇到这种情况的可能性是很小的。注意,在我们这个系列里面,所有的例子,楼主都用Notepad++测试通过,所以如果想跟着楼主一起来写,你最好也使用Notepad++吧。

 

好了,废话了那么久,让我们开始这一章的学习。

捕获与后向引用:

我们之前学习过的子表达式(),除了表明在()之间的元素属于一个单元——比如,\D\d+和(\D\d)+是不一样的两个模式,前者表明数字至少需要出现一次,后者表明非数字和数字组合至少需要出现一次——之外,还有捕获的功能。捕获的意思,就是把已经匹配成功的在()之间的串,存储在以数字1为基底的变量中。访问所捕获变量时用\1,\2进行访问。

像\1,\2,\3等也叫做后向引用,可以出现在模式当中完成一些用其他功能比较难以实现的功能,最典型的用法就是,通过后向引用来查看文章里面有没有重复出现的单词。

当然,可能有人也有疑问了,难道每一个子表达式()都有捕获作用吗?默认情况下,是的,但是如果不想要某个子表达式开启捕获功能,可以使用(?:)而不是()来关闭捕获功能仅仅保留子表达式的功能,这样表达式的匹配不会受到影响,但是不会存储子表达式匹配到的串。在大部分情况下,这是提高效率的一种方式。所以如果在使用子表达式之前能很确定我们不需要捕获里面的值,就请放心的关闭捕获功能吧。

 

环视:

环视是指不消耗文本内容而查看文本是否匹配的一种方式,有点像程序员熟悉的堆栈操作TOP,在不弹出栈底的同时查看栈底内容。这么说可能有点抽象,让我们先看看环视的定义和几个例子。

其实很好记忆,对吧?所有这四个元字符都以(?开头,如果不是否定,就用=,如果是否定,就用!。如果是后视,就再加上一个<在?后面。

环视就是典型的匹配了位置而不是字符的操作,对于环视,有个经典的应用,是往11位手机号码中插入短横线,把12345678912的电话号码输出为123-4567-8912。如果人工一条一条的来修改,是费力不讨好的事情,使用环视则可轻松完成。尝试使用模式 (?:(?=(\d{4})+$)) 替换

即可完成。其中,?:表示不需要捕获(因为捕获会降低性能,虽然很轻微,但是在不需要的时候最好还是关闭),(?=(\d{4})+$) 表示匹配的位置前面有至少1组4位数字并直接到行尾,这样匹配到的就是两个位置,分别在3和7后面,因为3后面有45678912而7后面有8912,分别替换这两位置为-,原字符串就变为123-4567-8912。

怎么样,见识到正则表达式的强大了没有?如果心动了就赶快练起来吧。平时工作中大家可以尝试刻意的制造一些机会去使用正则表达式,其实大家经常在工作中都会遇到一些需求,可以使用正则表达式来大幅简化任务,比如,提取email地址,代码审查的小工具,数字格式化等,这些任务我们当然可以用C#等重型工具来完成,但是如果掌握了正则,直接用文本编辑器就可以解决任务,是不是就更快了呢?所以大家遇到这种机会,一定不要放过使用啊。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值