正则表达式
列一下正则表达式中常用字符的用法,表格转自菜鸟教程
基本元字符:
- 符号
.
在[]
字符集中,其不再代表除换行符之外的任何一个字符,而是纯粹的点符号。 - 符号
^
在[]
字符集中,代表否定前缀,而不是定位字符开始的位置。
字符集:
捕获组和先行后行断言:
非打印字符和预定类:
下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
捕获组
捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部。一般一个小括号括起来就是一个捕获组。捕获组可以进行嵌套。以深度优先进行编号,在js中编号从1开始。
普通捕获组
每个捕获组都会按照深度优先的方式被自动分配一个组号,当要想使用某个捕获组时,通过组号来引用该捕获组。格式为:(exp)
。
例如存在这样一个正则表达式:(A)(B(C))
,其被扫描后编号的捕获组应该为:
例如在JS中,正则表达式为/mom ( and dad( and bay)?)?/gi
,字符串为"mom and dad and baby"
,则该模式存在两个捕获组,分别为( and dad( and bay)?)
和( and bay)
var text = "mom and dad and baby",
pattern = /mom ( and dad( and bay)?)?/gi;
var matches = pattern.exec(text);
alert(matches[0]); //"mom and dad and baby" 与整个模式匹配的字符串
alert(matches[1]); //" and dad and baby" 与第一个捕获组匹配的字符串
alert(matches[2]); //" and baby" 与第二个捕获组匹配的字符串
命名捕获组
即在模式中给对应的捕获组指定一个组名,当要想使用这个捕获组时,可以通过组名来引用该捕获组。格式为:(?<name>exp)
对于匹配一个日期(YYYY-MM-DD)的模式为(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
,这之中有3个命名捕获组,分别是(?<year>\d{4})
、(?<month>\d{2})
和(?<day>\d{2})
,它们的捕获组名依次为year、month、day。
命名捕获组也有编号,当模式中只有命名捕获组时,编号规则与普通捕获组类似。当模式中既有命名捕获组又有普通捕获组时,先忽略命名捕获组,对普通捕获组按照深度优先方式编号,当普通捕获组编号完成时,再对命名捕获组进行编号。
在JS中的replace
函数中,命名捕获组能快速调整字符串的顺序
var re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
"2015-01-02".replace(re, '$<day>/$<month>/$<year>');
//'02/01/2015'
捕获组的向后引用
模式中捕获组的向后引用用于重复搜索前面某个分组匹配的文本,避免了冗余。对于普通捕获组,使用\number
的格式进行引用,例如\1
代表引用第一个捕获组。对于命名捕获组,除了使用编号进行引用外,还可以使用\k<name>
的格式进行引用,例如\k<year>
代表引用一个组名叫year的捕获组。
例如正则表达式\b(\w+)\b\s+\1\b
可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\w+)
,这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符\s+
,最后是分组1中捕获的内容(也就是前面匹配的那个单词)\1
。
也可以将普通捕获组改写为命名捕获组\b(?<word>\w+)\b\s+\k<word>\b
,此时使用组名word来引用之前的捕获组。
非捕获组
非捕获组它参与匹配,但不捕获存储文本 ,也不针对组合进行计数,因此不会有组的编号,也不存在向后引用。格式为:(?:exp)
这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, industr(?:y|ies)
就是一个比 industry|industries
更简略的表达式。
先行断言、先行否定断言、后行断言和后行否定断言都属于非捕获组
https://www.cnblogs.com/chip/p/4278135.html
-
(?=pattern)
正向先行断言
代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配pattern。
例如对”a regular expression”这个字符串,要想匹配regular中的re,但不能匹配expression中的re,可以用”re(?=gular)
”,该表达式限定了re右边的位置,这个位置之后是gular,但并不消耗gular这些字符,将表达式改为”re(?=gular).
”,将会匹配reg,元字符.匹配了g,括号这一砣匹配了e和g之间的位置。 -
(?!pattern)
负向先行断言
代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配pattern。
例如对”regex represents regular expression”这个字符串,要想匹配除regex和regular之外的re,可以用”re(?!g)
”,该表达式限定了re右边的位置,这个位置后面不是字符g。负向和正向的区别,就在于该位置之后的字符能否匹配括号中的表达式。 -
(?<=pattern)
正向后行断言
代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配pattern。
例如对”regex represents regular expression”这个字符串,有4个单词,要想匹配单词内部的re,但不匹配单词开头的re,可以用”(?<=\w)re
”,单词内部的re,在re前面应该是一个单词字符。之所以叫后行断言,是因为正则表达式引擎在匹配字符串和表达式时,是从前向后逐个扫描字符串中的字符,并判断是否与表达式符合,当在表达式中遇到该断言时,正则表达式引擎需要往字符串前端检测已扫描过的字符,相对于扫描方向是向后的。 -
(?<!pattern)
负向后行断言
代表字符串中的一个位置,紧接该位置之前的字符序列不能匹配pattern。
例如对”regex represents regular expression”这个字符串,要想匹配单词开头的re,可以用”(?<!\w)re
”。单词开头的re,在本例中,也就是指不在单词内部的re,即re前面不是单词字符。当然也可以用”\bre”来匹配。
上一篇: 手机微博如何取消会员自动续费 微博续费
下一篇: PHP 常用的正则表达式例子