javascript 正则表达式分组、断言详解


Posted in Javascript onApril 20, 2017

 javascript 正则表达式分组、断言详解

  提示:阅读本文需要有一定的正则表达式基础。

       正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下。

       如果不用断言,以往用过的那些表达式,仅仅能获取到有规律的字符串,而不能获取无规律的字符串。

       举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的。因此,如果想获取页面标题(xxx),充其量只能写一个类似于这样的表达式:<title>.*</title>,而这样写匹配出来的是完整的<title>xxx</title>标签,并不是单纯的页面标题xxx。

       想解决以上问题,就要用到断言知识。

       在讲断言之前,读者应该先了解分组,这有助于理解断言。

       分组在正则中用()表示,根据小菜理解,分组的作用有两个:

       n  将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。

       n  分组之后,可以通过后向引用简化表达式。

        先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:

       \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}

       但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:

       \d{1,3}(.\d{1,3}){3}

       这样一看,就比较简洁了。

再来看第二个作用,就拿匹配<title>xxx</title>标签来说,简单的正则可以这样写:

       <title>.*</title>

       可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:

       <(title)>.*</\1>

       这个例子实际上就是反向引用的实际应用。对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。

       用\1这种语法,可以引用某组的文本内容,\1当然就是引用第1组的文本内容了,这样一来,就可以简化正则表达式,只写一次title,把它放在组里,然后在后边引用即可。

       以此为启发,我们可不可以简化刚刚的IP地址正则表达式呢?原来的表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下:

       (\d{1,3})(.\1){3}

       简单的解释下,把\d{1,3}放在一组里,表示为(\d{1,3}),它是第1组,(.\1)是第2组,在第2组里通过\1语法,后向引用了第1组的文本内容。

       经过实际测试,会发现这样写是错误的,为什么呢?

       小菜一直在强调,后向引用,引用的仅仅是文本内容,而不是正则表达式!

       也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。

       因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。

       至此,读者已经掌握了传说中的后向引用,就这么简单。

       接下来说说什么是断言。

       所谓断言,就是指明某个字符串前边或者后边,将会出现满足某种规律的字符串。

       就拿文章开篇的例子来说,我们想要的是xxx,它没有规律,但是它前边肯定会有<title>,后边肯定会有</title>,这就足够了。

       想指定xxx前肯定会出现<title>,就用正后发断言,表达式:(?<=<title>).*

       向指定xxx后边肯定会出现</title>,就用正先行断言,表达式:.*(?=</title>)

       两个加在一起,就是(?<=<title>).*(?=</title>)

       这样就能匹配到xxx。

     

       相信读者看到这,已经蒙了,不用急,待小菜慢慢讲来。

     

       其实掌握了规律,就很简单了,无论是先行还是后发,都是相对于xxx而言的,也就是相对于目标字符串而言。

       假如目标字符串后边有条件,可以理解为目标字符串在前,就用先行断言,放在目标字符串之后。

       假如目标字符串前边有条件,可以理解为目标字符串在后,就用后发断言,放在目标字符串之前。

       假如指定满足某个条件,就是正。

       假如指定不满足某个条件,就是负。

       断言只是条件,帮你找到真正需要的字符串,本身并不会匹配!

(?=X ) 零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,/w+(?=/d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
(?!X) 零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,/w+(?!/d) 与后不跟数字的单词匹配,而不与该数字匹配 。
(? 零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?
(? 零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?

       从断言的表达形式可以看出,它用的就是分组符号,只不过开头都加了一个问号,这个问号就是在说这是一个非捕获组,这个组没有编号,不能用来后向引用,只能当做断言。

       教程到此结束,希望大家阅读愉快!

Javascript 相关文章推荐
JS 参数传递的实际应用代码分析
Sep 13 Javascript
jquery下利用jsonp跨域访问实现方法
Jul 29 Javascript
JQuery入门——移除绑定事件unbind方法概述及应用
Feb 05 Javascript
使用jquery实现放大镜效果
Sep 02 Javascript
使用FlexiGrid实现Extjs表格效果方法分享
Dec 16 Javascript
【经验总结】编写JavaScript代码时应遵循的14条规律
Jun 20 Javascript
使用JavaScript为一张图片设置备选路径的方法
Jan 04 Javascript
Vue学习笔记进阶篇之函数化组件解析
Jul 21 Javascript
BootStrap下的弹出框加载select2框架失败的解决方法
Aug 31 Javascript
JS实现判断图片是否加载完成的方法分析
Jul 31 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
Jul 21 Javascript
JS实现小米轮播图
Sep 21 Javascript
jQuery插件FusionCharts绘制的3D双柱状图效果示例【附demo源码】
Apr 20 #jQuery
JS利用cookies设置每隔24小时弹出框
Apr 20 #Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
Apr 20 #Javascript
addEventListener()与removeEventListener()解析
Apr 20 #Javascript
详解用vue-cli来搭建vue项目和webpack
Apr 20 #Javascript
js禁止浏览器的回退事件
Apr 20 #Javascript
vue-cli入门之项目结构分析
Apr 20 #Javascript
You might like
PHP中的函数-- foreach()的用法详解
2013/06/24 PHP
用PHP生成excel文件到指定目录
2015/06/22 PHP
纯PHP代码实现支付宝批量付款
2015/12/24 PHP
JS图片浏览组件PhotoLook的公开属性方法介绍和进阶实例代码
2010/11/09 Javascript
再谈javascript面向对象编程
2012/03/18 Javascript
Jquery attr(&quot;checked&quot;) 返回checked或undefined 获取选中失效
2013/10/10 Javascript
jQuery focus和blur事件的应用详解
2014/01/26 Javascript
nodejs结合socket.io实现websocket通信功能的方法
2018/01/12 NodeJs
详解Angular结合zTree异步加载节点数据
2018/01/20 Javascript
微信小程序在线客服自动回复功能(基于node)
2019/07/03 Javascript
vue.js实现数据库的JSON数据输出渲染到html页面功能示例
2019/08/03 Javascript
结合axios对项目中的api请求进行封装操作
2020/09/21 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
如何在vue中使用video.js播放m3u8格式的视频
2021/02/01 Vue.js
[01:05:40]VG vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
[45:59]完美世界DOTA2联赛PWL S2 FTD vs GXR 第二场 11.22
2020/11/24 DOTA
详解Python中的文本处理
2015/04/11 Python
Python自动发邮件脚本
2017/03/31 Python
基于python select.select模块通信的实例讲解
2017/09/21 Python
Python字符编码与函数的基本使用方法
2017/09/30 Python
Python实现的排列组合计算操作示例
2017/10/13 Python
python学习之matplotlib绘制散点图实例
2017/12/09 Python
解决在Python编辑器pycharm中程序run正常debug错误的问题
2019/01/17 Python
Pandas之ReIndex重新索引的实现
2019/06/25 Python
python集合能干吗
2020/07/19 Python
PyQt5的QWebEngineView使用示例
2020/10/20 Python
德国价格合理的品牌商品购物网站:averdo
2019/03/21 全球购物
M.M.LaFleur官网:美国职业女装品牌
2020/10/27 全球购物
美国最大的购物网站:Amazon.com(亚马逊美国)
2020/05/23 全球购物
工业设计专业个人求职信范文
2013/12/28 职场文书
《爱如茉莉》教后反思
2014/04/12 职场文书
信息管理与信息系统专业求职信
2014/06/21 职场文书
企业消防安全责任书
2014/07/23 职场文书
开展党的群众路线教育实践活动情况汇报
2014/11/05 职场文书
协议书范文
2015/01/27 职场文书
2015年机关党委工作总结
2015/05/23 职场文书