JS正则相关知识分享

177 阅读2分钟

什么是正则

创建

字面量创建

ECMAScript 通过 RegExp 类型支持正则表达式。正则表达式使用类似 Perl 的简洁语法来创建:

let expression = /pattern/flags; 

构造函数创建

// 匹配第一个"bat"或"cat",忽略大小写
let pattern1 = /[bc]at/i;

// 跟 pattern1 一样,只不过是用构造函数创建的
let pattern2 = new RegExp("[bc]at", "i");

因为 RegExp 的模式参数是字符串,所以在某些情况下需要二次转义。所有元字符都必须二次转义,包括转义字符序列,如\n(\转义后的字符串是\,在正则表达式字符串中则要写成\\)。

在此不做过多说明 ,更加推荐使用字面量创建。

pattern(模式)

这个正则表达式的 pattern(模式)可以是任何简单或复杂的正则表达式,包括

  • 字符类
  • 限定符
  • 分组
  • 向前查找
  • 反向引用。

flags(标记)

每个正则表达式可以带零个或多个 flags(标记),用于控制正则表达式的行为。下面给出了表示匹配模式的标记。

名称flags意义
全局模式g查找字符串的全部内容,而不是找到第一个匹配的内容就结束
不区分大小写i查找匹配时忽略 pattern 和字符串的大小写
多行模式m表示查找到一行文本末尾时会继续查找
粘附模式y只查找从 lastIndex 开始及之后的字符串
Unicode 模式u启用 Unicode 匹配
dotAll 模式s表示元字符.匹配任何字符(包括\n 或\r)

使用不同模式和标记可以创建出各种正则表达式,比如:

// 匹配字符串中的所有"at" 
let pattern1 = /at/g; 

// 匹配第一个"bat"或"cat",忽略大小写 
let pattern2 = /[bc]at/i; 

// 匹配所有以"at"结尾的三字符组合,忽略大小写 
let pattern3 = /.at/gi; 

元字符

与其他语言中的正则表达式类似,所有元字符在模式中也必须转义,包括:

( [ { \ ^ $ | ) ] } ? * + .

元字符在正则表达式中都有一种或多种特殊功能,所以要匹配上面这些字符本身,就必须使用反斜杠来转义。

// 匹配第一个"bat"或"cat",忽略大小写
let pattern1 = /[bc]at/i; 

// 匹配第一个"[bc]at",忽略大小写
let pattern2 = /[bc]at/i; 

// 匹配所有以"at"结尾的三字符组合,忽略大小写
let pattern3 = /.at/gi; 

// 匹配所有".at",忽略大小写
let pattern4 = /.at/gi;

RegExp的实例属性

属性类型意义
global布尔值表示是否设置了 g 标记
ignoreCase布尔值表示是否设置了 i 标记
unicode布尔值表示是否设置了 u 标记
sticky布尔值表示是否设置了 y 标记
multiline布尔值表示是否设置了 m 标记
dotAll布尔值表示是否设置了 s 标记
lastIndex整数表示在源字符串中下一次搜索的开始位置,始终从 0 开始
source正则表达式的字面量字符串(不是传给构造函数的模式字符串)没有开头和结尾的斜杠
flags正则表达式的标记字符串始终以字面量而非传入构造函数的字符串模式形式返回(没有前后斜杠)

RegExp实例方法

exec()

用于配合捕获组使用。这个方法只接收一个参数,即要应用模式的字符串。

  • 如果找到了匹配项,则返回包含第一个匹配信息的数组
  • 如果没找到匹配项,则返回null。

返回的数组虽然是 Array 的实例,但包含两个额外的属性:

  • index (字符串中匹配模式的起始位置)
  • input(要查找的字符串)

这个数组的第一个元素是匹配整个模式的字符串,其他元素是与表达式中的捕获组匹配的字符串。如果模式中没有捕获组,则数组只包含一个元素。

let text = "mom and dad and baby"; 
let pattern = /mom( and dad( and baby)?)?/gi;
let matches = pattern.exec(text);
[
  'mom and dad and baby',
  ' and dad and baby',
  ' and baby',
  index: 0,
  input: 'mom and dad and baby',
  groups: undefined
]

如果模式设置了全局标记,则每次调用 exec()方法会返回一个匹配的信息。如果没有设置全局标

记,则无论对同一个字符串调用多少次 exec(),也只会返回第一个匹配的信息

let text = "cat, bat, sat, fat";
let pattern = /.at/g;
let matches1 = pattern.exec(text);
// [ 'cat', index: 0, input: 'cat, bat, sat, fat', groups: undefined ]

let matches2 = pattern.exec(text);
// [ 'bat', index: 5, input: 'cat, bat, sat, fat', groups: undefined ]

let matches3 = pattern.exec(text);
// [ 'sat', index: 10, input: 'cat, bat, sat, fat', groups: undefined ]

test()

接收一个字符串参数。如果输入的文本与模式匹配,则参数返回 true,否则返回 false。这个方法适用于只想测试模式是否匹配,而不需要实际匹配内容的情况。test()经常用在 if 语句中。

let text = "000-00-0000"; 
let pattern = /\d{3}-\d{2}-\d{4}/; 
if (pattern.test(text)) { 
  console.log("The pattern was matched."); 
}

RegExp 构造函数属性

主要属性

全 名简写说明
input$_最后搜索的字符串(非标准特性)
lastMatch$&最后匹配的文本
lastParen$+最后匹配的捕获组(非标准特性)
leftContext$`input 字符串中出现在 lastMatch 前面的文本
rightContext$'input 字符串中出现在 lastMatch 后面的文本
let text = "this has been a short summer"; 
let pattern = /(.)hort/g; 
if (pattern.test(text)) { 
  console.log(RegExp.input); // this has been a short summer 
  console.log(RegExp.leftContext); // this has been a 
  console.log(RegExp.rightContext); // summer 
  console.log(RegExp.lastMatch); // short 
  console.log(RegExp.lastParen); // s 
}
/* 
 * 注意:Opera 不支持简写属性名
 * IE 不支持多行匹配
 */ 
if (pattern.test(text)) { 
 console.log(RegExp.$_); // this has been a short summer 
 console.log(RegExp["$`"]); // this has been a 
 console.log(RegExp["$'"]); // summer 
 console.log(RegExp["$&"]); // short 
 console.log(RegExp["$+"]); // s 
}

其他属性

RegExp 还有其他几个构造函数属性,可以存储最多 9 个捕获组的匹配项。这些属性通过 RegExp.

1 RegExp.1~RegExp.9 来访问,分别包含第 1~9 个捕获组的匹配项。

let text = "this has been a short summer"; 
// ...表示字符占位 有多少个点 就可以代表几个字符
let pattern = /(..)or(.....)m(.)/g; 
if (pattern.test(text)) { 
  console.log(RegExp.$1); // sh 
  console.log(RegExp.$2); // t sum
  console.log(RegExp.$3); // e
}