0%

JavaScript正则表达式手册

关于本手册

正则表达式是一种跨编程语言的字符匹配方法,在语法层次之外还有具体的几种实现,本手册只使用JavaScript语言。

本手册分为两个部分,语法部分和方法部分。

语法部分不讲解正则表达式的语法,只试图快速给使用者快速的指引,请尽量在下列语法列表中查找自己需要的内容,因表格空间限制,无法解释清楚的内容请通过连接直接进行访问具体内容。

方法部分搜集了Javascript字符串和正则对象的相关方法,讲解了如何使用。

语法

语法形式 语法名称 语法含义 注意事项
[exp] 字符组-普通 整个方括号表示一个字符,里面的字符出现一个就可以匹配 元字符在字符组内失效;-^在字符组内可能有其他含义;
[^exp] 字符组-排除型字符组 整个方括号表示一个字符,不出现里面的字符就可以匹配 同上
(exp) 分组-普通 整个圆括号内是一个独立部分,匹配内容会被记录 可以通过序号引用
(?:exp) 分组-不被记录的分组 分组不占用序号,不被记录 不能被引用
(?<groupName>exp) 分组-命名分组 分组有序号,同时有名字 可以通过序号或者名字引用
{n} 重复限制 n次
{n,} 重复限制-贪婪 n或更多次,尽可能得多
{n,m} 重复限制-贪婪 n~m次,尽可能得多
? 重复限制-贪婪 0~1次,尽可能得多 等价于{0,1}
* 重复限制-贪婪 0或更多次,尽可能得多 等价于{0,}
+ 重复限制-贪婪 1或更多次,尽可能得多 等价于{1,}
{n,}? 重复限制-懒惰 n或更多次,尽可能得少
{n,m}? 重复限制-懒惰 n~m次,尽可能得少
?? 重复限制-懒惰 0~1次,尽可能得少 等价于{0,1}
*? 重复限制-懒惰 0或更多次,尽可能得少 等价于{0,}
+? 重复限制-懒惰 1或更多次,尽可能得少 等价于{1,}
\b 匹配位置 单词的开始或者结束
(?=exp) 零宽度正预测先行断言 1找到匹配exp的内容
2向前查找特定内容
不返回断言匹配内容
(?<=exp) 零宽度正回顾后发断言 1找到匹配exp的内容
2向后查找特定内容
不返回断言匹配内容
(?!exp) 零宽度负预测先行断言 1找到不匹配exp的内容
2向前查找特定内容
不返回断言匹配内容
(?<!exp) 零宽度负回顾后发断言 1找到不匹配exp的内容
2向后查找特定内容
不返回断言匹配内容
分支 多个表达式中满足一个即达成匹配 注意:此处应该是半角字符
. 元字符 匹配换行之外的单个字符
\w 元字符 匹配字母数字下划线之一的单个字符
\s 元字符 匹配任意空白的单个字符
\d 元字符 匹配数字的单个字符
\b 元字符-匹配位置 匹配单词边界 不返回匹配内容
\W 元字符 匹配\w之外的单个字符
\S 元字符 匹配\s之外的单个字符
\D 元字符 匹配\d之外的单个字符
\B 元字符-匹配位置 匹配\b之外的单个字符 不返回匹配内容
^ 元字符-匹配位置 字符串开始 不返回匹配内容
$ 元字符-匹配位置 字符串结束 不返回匹配内容
(exp) 普通分组 分组中的内容会被当作一个整体
(?:exp) 不被记录的分组 分组但不被记录,不被分配序号
\N 按序号引用分组 在第N个分组之后引用该分组 N从1开始计数
\k<groupName> 按名称引用分组 在groupName分组后,引用它
i 匹配模式 不区分大小写
g 匹配模式 全局匹配 从头到尾匹配一遍
s 匹配模式 允许 .匹配换行(输入的换行,\r\n
m 匹配模式 允许^$在每一行生效 ^$不再只匹配整个字符串的开头和结尾
u 匹配模式 识别unicode码位 受到ucs-2编码方式的限制,相关操作方法并不一定准确
y 匹配模式 迟滞模式 从字符串的lastIndex索引处匹配一次
\ 对元字符转义
\p{name} 匹配unicode属性
\unnnn Unicode代码中十六进制代码为nnnn的字符 注意是16进制的
\u{nnnn} Unicode代码中十六进制代码为nnnn的字符,支持辅助平面字符
\a 元字符 报警字符
\t 元字符 制表符,Tab
\r 元字符 回车
\v 元字符 竖向制表符
\f 元字符 换页符
\n 元字符 换行符
\e 元字符 Escape
\onn 元字符 ASCII代码中八进制代码为nn的字符
\xnn 元字符 ASCII代码中十六进制代码为nn的字符

字符组

字符组:character classes

字符组类似一个独立的世界,进入字符组,有些规则需要改变。

字符组的格式为[],其中的内容顺序无关,内容中只要有一项满足要求就实现了匹配,一个字符组只匹配一个字符。

在字符组中,-^可能是元字符,除此之外,外面的元字符在字符组中都是普通字符。

字符组元字符-

它表示从它之前到它之后字符之间的范围。

-不是元字符的3种情况

  • -出现在字符组之外
  • -在字符组之内,紧跟在[或者[^之后,例:[-,]或者[^-,]
  • -在字符组之内,但在末尾,例:[,-]

字符组元字符^

表示所在的字符组是一个排除型字符组。

^成为字符组元字符条件:^必须是[]中第一个字符,这也就构成了排除型字符组。

排除型字符组

表示匹配一个未列出的字符。

两层含义:

  • 要匹配一个字符
  • 要匹配的字符不能是这个字符组内的

注意事项

  • 表示数字和字母的范围,需要依据字符ASCII码,从小到大进行。

例如:[z-a][9-0]都不是正确的正则表达式。

PS:ASCII顺序中,数字<大写字母<小写字母。

  • 跨数字、大写字母、小写字母段表示范围,可能不小心扩大范围。

例如:[0-z]会包含数字,大写字母,小写字母,还会包括ASCII表中的其他字符(比如@),因为这三段字符不是连续的。

所以不确定的情况下,不要轻易跨段表示范围。

  • 在字符组内使用-,要格外注意位置。

分支

使用|连接多个表达式,表示在多个表达式之间进行选择,任何一个表达式满足即可。

可以使用()限制分支表达式的范围。

分组

普通分组

格式:(exp)
创建分组,分配组序号,不命名

不被记录的分组

格式:(?:exp)

这种方式不影响既有的分组序号。

命名分组

命名分组:(?<groupName>)

引用分组

在表达式中引用前面的分组。

使用序号引用分组

回溯引用就是使用\N引用前面的分组内容。

N一般从1开始,表示第N个匹配分组的内容。

使用名称引用分组

引用分组:\k<groupName>

断言

  • 以下exp_out不是断言的一部分,只是为了说明断言的使用场景。

  • 以下exp是断言中的表达式,均不会返回它匹配的内容

零宽度正预测先行断言

格式:exp_out(?=exp)

含义:找到满足exp表达式的位置,向前查找满足exp_out表达式的内容并返回。

零宽度正回顾后发断言

格式:(?<=exp)exp_out

含义:找到满足exp表达式的位置,向后查找满足exp_out表达式的内容并返回。

零宽度负回顾后发断言

格式:exp_out(?!exp)

含义:找到排除exp表达式的位置,向前查找满足exp_out表达式的内容并返回。

零宽度负回顾后发断言

格式:(?<!exp)exp_out

含义:找到排除exp表达式的位置,向后查找满足exp_out表达式的内容并返回。

匹配unicode属性

unicode把字符按照不同的标准进行了分类,另外还针对不同的语言对符号做了分类。

可以在后面的参考部分找到完整的分类情况。

字符类型

格式:\p{P}

含义:匹配标点符号。替换其中的P,可以匹配指定类型的字符。

具体的字符类型见参考内容。

语言类型

格式:\p{sc=Han}

含义:匹配中文字符。替换其中的Han,可以匹配指定语言字符。

具体的语言类型见参考内容。


正则相关编程接口

字符串实例的方法

match(reg)

根据参数,找到一个或者多个匹配到的内容,返回一个数组。

支持全局模式

采用了全局匹配模式的情况

返回一个数组,里面按顺序存储了所有匹配子串

没有采用全局匹配模式的情况

返回一个数组和一些附加信息。

  • 数组中存储第一个匹配子串的信息;
  • 附加信息包括groupsindexinput信息。
  • input是原始字符串

在没有采用分组时,返回的数组只包括第一个匹配子串;
在采用了分组时,返回的数组依次包括第一个匹配子串、第一个匹配的分组内容

在采用了分组且命名了分组时,groups是一个数据对象,key为分组名称,value为第一个匹配的分组内容;否则为undefined

replace(pattern, replacement)

把字符串中指定子串替换成新字符串,不改变原字符串。
`

  • 如果pattern是一个字符串,则只替换找到的第一个子串。
  • 如果pattern是正则表达式,则根据正则表达式规则进行替换,支持全局模式。
  • 如果replacement是一个字符串,则匹配到的字串要被替换为它的内容,这里存在一些特殊字符
    • $$ 表示$
    • $& 表示匹配到的字符串。这个字符不是一个可以直接使用的变量,而是一个标记,会被替换
    • $` 表示当前匹配的子串左边的内容
    • $' 表示当前匹配的子串右边的内容
    • $n 表示正则匹配到的第几个分组。如果没有分组,则只能表示字面量。这里的索引从1开始。
    • $<name> 其中name表示匹配到的分组名称,如果没有分组,则表示字面量;如果存在分组,但name和正则中的分组名称不符合,则表示空字符串(会把每个匹配项目替换成空字符串);如果存在分组且name吻合,则表示匹配到的分组内容。
  • 如果replacement是一个函数,会对每个匹配项执行这个函数,函数的返回值作为替换字符串。这个函数的参数如下:
    • match:匹配的子串。类似上面说的$&
    • p1,p2,p3…:依次表示这次匹配到的各个分组(捕获到的子串)。类似上面说的$n。如果没有分组,则这些参数都没有。
    • offset:此次匹配在原字符串中的索引位置
    • string:原字符串。
    • groups:如果存在命名分组,则这个参数是一个对象,里面用key/value存储分组名称和匹配到的子串;否则这个对象是undefined

search(reg)

搜索字符串中是否含有指定内容,返回第一次找到的索引位置,没有找到返回-1

支持全局模式

split([separator[, limit]])

根据参数,把字符串拆分为数组

  • 如果separator是空字符串,会返回UTF-16字符数组,但是这个分割可以能不是想要的内容,。
  • 如果separator省略或者没有找到对应子串,则返回一个数组,里面只包含原字符串。
  • 如果separator出现在原来字符串的头尾,也是有效果的,会分别在返回内容的头尾添加空字符串。所以如果separator和原字符串一样,会返回两个空字符串组成的数组。
  • limit 需要是个非负数,用它来限制返回数组的长度。
    • 如果limit为0,返回空数组
    • 如果limit比数组长度大,那么它没有实际的效果。

这个方法,是否全局模式无所谓,默认就是全局模式。

RegExp对象

上述字符串方法中,都用到了RegExp对象,它就是一个正则表达式的抽象。

中没有

创建一个RegExp对象

有两种途径创建一个RegExp对象

  • 字面量方式。通过/exp/这样的方式创建。匹配模式可以加在后面,类似这样/exp/gi
  • 调用构造方法。传入正则表达式内容,和匹配模式也可以创建一个字符串。

    test(str)

    测试str是否匹配当前正则表达式

    exec(str)

    在指定的字符串str上执行一个搜索匹配,这个方法和字符串上的match方法类似。

在使用了g或者y模式时,可以使用exec方法逐一遍历匹配内容。

注意事项

进制问题

  • 使用字符串示例的“codePointAt”得到的是10进制的码点
  • 正则表达式中的\unnnn\u{nnnn},要求nnnn是16进制的字符串

RegExp构造方法

  • 参数中的正则表达式需要注意字符串转义,把\转义为\\

参考

unicode 字符分类

unicode 字符分类-语言