正则表达式

创建一个正则规则

第一种是使用 / 符号把正则包裹起来

1
var reg = /ab+c/g

第二种是使用 new 的方法

1
2
new RegExp('ab+c','g');
new RegExp(/ab+c/,'g');

要注意的是,在新建一个正则的时候,还有 flags 可以选择:

  • g 全局匹配;找到所有匹配,而不是在第一个匹配后停止
  • i 忽略大小写
  • m 多行; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。
  • u Unicode; 将模式视为Unicode序列点的序列
  • y 粘性匹配; 仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。

常用特殊字符

  • . 匹配任意单个字符,只能匹配一个字符。
  • \d 匹配任意单个数字,等价于[0-9]等价。
  • \D 匹配任意单个非数字。等价于[^0-9]。
  • \w 匹配任意单个字母、数字、下划线。等价于 [A-Za-z0-9_]。
  • \W 匹配任意单个非字母、数字、下划线。等价于 [^A-Za-z0-9_]。
  • \s 匹配单个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格
  • \S 匹配一个非空白符。
  • ^ 代表输入开始。如果在 [] 中出现,代表取补集。
  • $ 代表输入结束。
  • * 代表前面的模式 0+ 次。
  • + 代表前面的模式 1+ 次。
  • ? 代表前面的模式 0 或 1 次。
  • x|y 匹配 x 或 y。
  • x{n,m} 代表有 n~m 个 x,m 可省略。

括号的用法

圆括号

() 是为了提取匹配的字符串,有字符匹配多少。

方括号

[] 是为了匹配一个范围的字符串,例如 /[0-9]/ 只匹配 0~9 中的一个数字。

花括号

{} 表示匹配的数量。

区别

  • (0-9) 匹配 '0-9' 字符串。
  • [0-9] 匹配 0~9 数字。
  • {1-9} 代表应该有 1 ~ 9 的数量,不可以单独使用。

进阶用法

  • x(?=y) 仅匹配被y跟随的x。举个例子,/Jack(?=Sprat)/,如果”Jack”后面跟着sprat,则匹配之。
  • x(?!y) 仅匹配不被y跟随的x。举个例子,/\d+(?!.)/ 只会匹配不被点(.)跟随的数字。

正则的 Function

RegExp.prototype.exec()

方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null

这里的数组结构为:

1
2
3
4
5
6
7
{
[ '匹配的全部字符串',
'...括号中的分组捕获'
],
index: '匹配到的字符位于原始字符串的基于0的索引值',
input: '原始字符串'
}

执行例子:

1
/(a).?(c)/.exec('abcddd')

得到结果:

1
2
3
4
5
{
["abc","a","c"],
index: 0,
input: "abcddd"
}

RegExp.prototype.test()

执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 truefalse

执行正则表达式和 String对象之间的一个搜索匹配。返回正则表达式在字符串中首次匹配项的索引。否则,返回 -1。与 RegExp.prototype.test() 相似。

String.prototype.match()

字符串的匹配,与 RegExp.prototype.exec() 相似,但是返回值根据不同的情况返回不同的值。

  • 没有 g 标志,返回结果与 RegExp.prototype.exec() 相同;
  • g 标志,且匹配成功,返回一个 Array,它包含所有匹配的子字符串而不是匹配对象。
  • g 标志,如果没有匹配到,则返回 null
  • 不传入参数,返回空数组 []
  • 当参数是一个字符串或一个数字,它会使用new RegExp(obj)来隐式转换成一个 RegExp。如果它是一个有正号的正数,RegExp() 方法将忽略正号。

String.prototype.replace()

参数有 4 个,但不能同时使用:

  • regexp:正则,第一个匹配内容会被第二个参数的返回值替换掉。
  • substr:字符串,第一个匹配的字符串会被第二个参数替换。
  • newSubStr:字符串,该字符串中可以内插一些特殊的变量名。
  • function:函数,该函数的返回值将替换掉第一个参数匹配到的结果。

也即只能填写两个参数:第一个参数,只能是要 被替换 的正则或是字符串;第二个参数是要 替换掉 的字符串或者函数。

且要注意:如果没有 g 标志,则之替换第一个匹配到的内容。

这里详细讲一下 function 的用法

function 接受的参数为:

  • match:匹配的子串
  • p1,p2, ...:代表第n个括号匹配的字符串。
  • offset:匹配到的子字符串在原字符串中的偏移量。
  • string:被匹配的原字符串。

通过如下例子可以比较清晰地认识:

1
2
3
4
5
//声明替换函数
var replacer = (match, p1, p2, offset, string) => {
return `-${match}-${p1}-${p2}-${offset}-${string}-`
}
'0abcddd'.replace(/(a).?(c)/g, replacer)

输出结果

1
"0-abc-a-c-1-0abcddd-ddd"

match 指代匹配到的子串 abcp1,p2 代表 (a)(c)匹配到的子串,offset 代表偏移量 1, string 代表原字符串。返回值为新字符串,把匹配的 abc 替换成 -abc-a-c-1-0abcddd-

参考文献

MDN