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 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。 |
|
(?<!X) |
零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配 |
从断言的表达形式可以看出,它用的就是分组符号,只不过开头都加了一个问号,这个问号就是在说这是一个非捕获组,这个组没有编号,不能用来后向引用,只能当做断言。
教程到此结束,希望大家阅读愉快!
# javascript
# 正则表达式分组、断言详解
# js
# 正则表达式
# 断言
# 详解JavaScript中jQuery和Ajax以及JSONP的联合使用
# JavaScript断言与类型守卫及联合声明超详细介绍
# 的是
# 后向
# 就用
# 放在
# 时才
# 会有
# 中有
# 而不
# 可以通过
# 组里
# 可以看出
# 相对于
# 跟在
# 就拿
# 与该
# 都是
# 而不是
# 第一个
# 就能
相关文章:
宝塔新建站点报错如何解决?
如何通过万网虚拟主机快速搭建网站?
官网建站费用明细查询_企业建站套餐价格及收费标准指南
网站制作公司,橙子建站是合法的吗?
深圳网站制作培训,深圳哪些招聘网站比较好?
小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?
网站设计制作企业有哪些,抖音官网主页怎么设置?
c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】
如何解决VPS建站LNMP环境配置常见问题?
赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?
如何在景安云服务器上绑定域名并配置虚拟主机?
商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
Swift中swift中的switch 语句
*服务器网站为何频现安全漏洞?
网站制作免费,什么网站能看正片电影?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
如何用PHP快速搭建CMS系统?
建站之星如何取消后台验证码生成?
php json中文编码为null的解决办法
如何快速查询域名建站关键信息?
如何快速配置高效服务器建站软件?
平台云上自主建站:模板化设计与智能工具打造高效网站
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
如何确保西部建站助手FTP传输的安全性?
建站org新手必看:2024最新搭建流程与模板选择技巧
广州建站公司哪家好?十大优质服务商推荐
宝塔新建站点为何无法访问?如何排查?
微信h5制作网站有哪些,免费微信H5页面制作工具?
再谈Python中的字符串与字符编码(推荐)
建站之星安装需要哪些步骤及注意事项?
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
详解jQuery停止动画——stop()方法的使用
文字头像制作网站推荐软件,醒图能自动配文字吗?
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
宝塔建站助手安装配置与建站模板使用全流程解析
存储型VPS适合搭建中小型网站吗?
建站之星2.7模板:企业网站建设与h5定制设计专题
建站主机选择指南:服务器配置与SEO优化实战技巧
如何通过FTP服务器快速搭建网站?
较简单的网站制作软件有哪些,手机版网页制作用什么软件?
jQuery 常见小例汇总
宁波免费建站如何选择可靠模板与平台?
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
制作表格网站有哪些,线上表格怎么弄?
如何通过虚拟主机快速搭建个人网站?
大连网站制作公司哪家好一点,大连买房网站哪个好?
昆明网站制作哪家好,昆明公租房申请网上登录入口?
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?
*请认真填写需求信息,我们会在24小时内与您取得联系。