正则表达式中问号?的正确用法
正则表达式中“?”的用法大概有以下几种
- 用作重复次数限制功能,用在子表达式后,表示子表达式内容可以出现0次或1次
- 用于表示非贪婪匹配,必须跟在表示重复的符号后,即必须跟在 * + ? {n} {n,} {n,m} 之后
- 用于表示非获取匹配,用在分组匹配中,表示不缓存与某分组匹配的内容
- 用于断言
1. 直接跟随在子表达式后面
这种方式是最常用的用法,具体表示匹配前面的一次或者0次,类似于{0,1},如:abc(d)?可匹配abc和abcd
2. 非贪婪匹配
关于贪婪和非贪婪,贪婪匹配的意思是,在同一个匹配项中,尽量匹配更多所搜索的字符,非贪婪则相反。正则匹配的默认模式是贪婪模式,当?号跟在如下限制符后面时,使用非贪婪模式(*,+,?,{n},{n,},{n,m})
如正则表达式 \S+c 匹配字符串aaaacaaaaaaac的结果是aaaacaaaaaaac,而\S+?c则会优先匹配aaaac
3. 非获取匹配
当我们使用正则表达式的时候,捕获的字符串会被缓存起来以供后续使用,具体表现为每个()中的表达式所匹配到的内容在进行正则匹配的过程中,都会被缓存下来,如以下代码
var testReg=/(a+)(b*)c/;
testReg.test('aaaabbbccc');//输出true
console.log(RegExp.$1);//输出aaaa
console.log(RegExp.$2);//输出bbb
但是,如果在子分组中加入?:之后,分组依然成立,但是不会被缓存下来,看以下代码
var testReg=/(a+)(?:b*)c/;
testReg.test('aaaabbbccc');//输出true
console.log(RegExp.$1);//输出aaaa
console.log(RegExp.$2);//输出""
4.断言
我们知道,正则表达式中大部分的结构所匹配的文本最终会出现在匹配结果中,但也有一部分结构并不真正匹配文本,而只是负责判断某个位置左/右侧是否符合要求,这种结构被称为断言
常用的断言有以下四种
(?=pattern)
非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。(?!pattern)
非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。(?<=pattern)
非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。(?<!patte_n)
非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。
以下的段落中,我们将统一使用pattern表示断言的条件
?=pattern和?<=pattern分别表示匹配断言成立时左侧和右侧的文本,只有断言成立了,左侧或右侧的文本才会被匹配,但断言所匹配的结果并不会出现在匹配结果中,具体例子可以看以下代码
var testReg=/test(?=123)/;
var result=testReg.exec('test123');
console.log(result[0])//输出testvar result2=testReg.exec('test12');
console.log(result2)//输出null
我们可以看到test(?=123)可以匹配到test123中的test,但是并不能匹配test12中的test,对于?<=pattern同理,可以看以下代码
var testReg=/(?<=123)test/;
var result=testReg.exec('123test');
console.log(result[0])//输出testvar result2=testReg.exec('12test');
console.log(result2)//输出null
同样(?=123)test可以匹配到123test中的test,匹配不到12test中的test,并且匹配结果同样不包含断言
对于?!pattern和?<!pattern可以看成是上面两个表达式的取反,分别匹配断言不成立时的左侧和右侧文本,具体可以看以下代码
var testReg=/test(?!123)/;
var result=testReg.exec('test123');
console.log(result)//输出nullvar result2=testReg.exec('test12');
console.log(result[0])//输出test
var testReg=/(?<!123)test/;
var result=testReg.exec('123test');
console.log(result)//输出nullvar result2=testReg.exec('12test');
console.log(result2[0])//输出test
如上我们可以看到这个时候要匹配到左侧或者右侧的test,需要括号里的断言不成立时,才能匹配的到了
参考资料:
https://blog.csdn.net/u014762221/article/details/68953155
https://www.jianshu.com/p/08c2fa742c1b
正则表达式中问号?的正确用法相关推荐
- Spring MVC中Session的正确用法之我见02
Spring MVC中Session的正确用法之我见 Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置 ...
- php正则表达式小括號,正则表达式中的小括号用法
正则表达式中的小括号用法 小括号中的连续字符作为可选: "Nov" -match "\bNov(ember)?\b" 返回true "Novembe ...
- 正则表达式中grep,sed的用法(包括基本的正则表达式和扩展的正则表达式)
一 正则表达式 Basic REGEXP:基本正则表达式 Extended REGEXP:扩展正则表达式 (正则表达式是使得计算机变成智能化的重要途径) 1.1 基本正则表达式 . : 表示匹配任 ...
- C#中dynamic的正确用法 以及 typeof(DynamicSample).GetMethod(Add);
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- 改善C#程序的建议2:C#中dynamic的正确用法
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- C#中dynamic的正确用法
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- memset linux 头文件,linux中memset的正确用法
[起因]希望对各种类型的数组进行初始化,避免野值 memset函数将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始 ...
- 正则表达式中的小括号用法
小括号中的连续字符作为可选: "Nov" -match "\bNov(ember)?\b" 返回true "November" -m ...
- Python正则表达式中问号的四种用法
1.原文符号 因为?在正则表达式中有特殊的含义,所以如果想匹配?本身,则需要转义,? 2.有无量词 问号可以表示重复前面内容的0次或一次,也就是要么不出现,要么出现一次. 3.(非)贪婪匹配 贪婪匹配 ...
最新文章
- 时间:2014年3月27日文件和目录操作函数
- oracle如何查询系统变量数据,Oracle如何对IN子查询使用绑定变量(转)
- 四、Go语言复合数据类型(上)
- python下载文件的11种方式_Python 中常见的几种下载文件方法
- oracle数据库导入导出expdp/impdp命令详细操作过程
- 卷积神经网络minst的verilog实现
- 织梦 php 传值,php获取post参数的几种方式
- word树状分支图_带你看懂市政管道工程图
- python小括号、中括号和大括号的区别
- ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES) 的解决方案
- C语言程序每个语句都必须有行号,2012年计算机二级C语言程序设计基本概念考点归纳...
- CUDA文件缺失解决方法——以cudart64_110.dll not found为例
- 程序猿崛起2——互联网时代下的新潮流和新活法
- (附源码)springboot校园疫情智慧防控微信小程序 毕业设计 011133
- 微软,谷歌和雅虎收购比较
- 怎么在mysql中编辑数据库_navicat怎么修改数据库名
- 中小型互联网公司技术研发部门组织架构及职责
- 回顾过去 展望未来(写给自己)
- Windows版Redis和Redis Desktop Manager安装
- 新站上线完整详细的SEO优化方案