欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

正则表达式

程序员文章站 2022-06-06 17:44:07
...

列一下正则表达式中常用字符的用法,表格转自菜鸟教程

基本元字符:
正则表达式

  • 符号.[]字符集中,其不再代表除换行符之外的任何一个字符,而是纯粹的点符号。
  • 符号^[]字符集中,代表否定前缀,而不是定位字符开始的位置。

字符集:
正则表达式


捕获组和先行后行断言:
正则表达式


非打印字符和预定类:
正则表达式


下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
正则表达式


捕获组

捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部。一般一个小括号括起来就是一个捕获组。捕获组可以进行嵌套。以深度优先进行编号,在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”来匹配。
相关标签: 正则表达式