JavaScript RegExp()构造函数中使用字符串或模版字符串的理解

发布时间:9/4/2025
更新时间:9/4/2025
展示:367

使用字符串

先上一个小例子:

const regex1 = /\d+/;
const regex2 = new RegExp("\d+");

这是一个匹配多个数字的正则,为什么这里使用RegExp构造函数时,需要用两个斜杠?

因为这里有两层转义机制在同时工作:

  1. 字符串转义机制
  2. 正则表达式转义机制

使用new RegExp("\d+")时,字符串 "\d+" 会先被 JavaScript 字符串解析器 处理:

  • \ 被解释为 一个普通的反斜杠字符 \
  • 所以内存中的字符串实际上变成了: \d+

然后,这个字符串 \d+ 被传递给 RegExp 构造函数,正则表达式引擎看到的是:

  • \d 被解释为 匹配数字 的正则元字符
  • + 被解释为 量词

也就是说我们使用new RegExp()构造函数时,目标是为了得到类似\d+这样的字符串,但是由于字符串中的转义机制,使得用起来变得麻烦了一点。

为什么会有转义机制呢? 原来是为了在字符串中表示一些特殊字符,例如单引号、双引号、换行等,我们约定使用转义字符 \ 来进行转义,例如:

  • \' 表示单引号
  • \" 表示双引号
  • \n 表示换行
  • \t 表示制表符

当转义字符 \ 遇到上面的符号就能正确表示出来,如果转义字符 \ 后面碰到了它不认识的字符,他就会原封不动的返回,如 "\a" => "a",这就导致我们不能在字符串中单独使用 "\" 表示一个 '\' 符号,必须使用 '\' 表示

明白了转义机制,再来使用RegExp构造函数时,就会变得简单了很多。

我们只要清楚目标正则表达式是什么样的,然后让字符串能转成这个正则表达式,就可以轻松使用RegExp构造函数传递字符串。

现在来一个难一点的例子。现在要在一段markdown字符串中,拿到其中所有的图片链接

// markdown 图片链接格式: ![name](url)
// 其中 name 是图片的名称,url 是图片的地址

// 正则表达式
const reg1 = /!\[.+?\]\(.+?\)/g;

// RegExp 传递字符串
const reg2 = new RegExp("!\[.+?\]\(.+?\)",'g');

const markdown = "![图片1](https://example.com/image1.jpg)\n![图片2](https://example.com/image2.jpg)";

const result = markdown.matchAll(reg2)
result.forEach(item=>console.log(item))

目标字符串: !\[.+?\]\(.+?\)
用字符串表示时需要将 \\ 转义,最后得到 :!\[.+?\]\(.+?\)

讲解一下 reg1 这个正则表达式:

  • ! 匹配一个感叹号
  • \[ 匹配一个左中括号,因为[]在正则表达式中表示字符集,所以单独表示一个“[”符号就需要转义
  • .+? 匹配除换行符外任意多个字符(非贪婪模式)
  • \] 匹配一个右中括号,同上“[”符号一样,需要转义
  • \( 匹配一个左括号,() 在正则表达式中表示分组,所以需要转义
  • .+? 匹配除换行符外任意多个字符(非贪婪模式)
  • \) 匹配一个右括号,同上“(”符号一样,需要转义

什么是 非贪婪模式? 非贪婪模式就是尽可能少的匹配字符。在默认情况下,正则匹配都是贪婪模式匹配,也就是尽可能长的匹配字符串。类似下面这种:

const reg = /\[.+\]/
reg.exec('[123]123456]789')
// '[123]123456]'

? 在正则中本来是表示匹配0个或1个字符,但是紧跟在量词后面,? 就表示非贪婪模式,即尽可能少的匹配字符。

const reg = /\[.+?\]/
reg.exec('[123]123456]789')
// '[123]'

使用模版字符串

模版字符串用久了就会产生一种不用转义字符的错觉,是什么字符在模版字符串中就是什么样的,其实不完全是这样的,看下面这个例子

const str1 =`\w\w\w` 
console.log(str1)
// 输出:www
const str2 =`\w\w\w`
console.log(str2)
// 输出:'\w\w\w'

字符串模版最终会转换为字符串,这里的 \w\w\w 会变成字符串 '\w\w\w',所以最后输出的也是 ’www‘。

所以在 RegExp 构造函数中使用字符串模版定义正则也和字符串相似,需要用\ 表示 \

当然如果不想转义序列,也可以用 String.raw() 方法

const str = String.raw`\w\w\w`
console.log(str)
// 输出:\w\w\w
目录
  • 使用字符串
  • 使用模版字符串