《深入理解 RegExp:边界、环视与非捕获组详解》

196 阅读2分钟

RegExp

\b 和 \B边界

- \b: 单词编辑
	- 单词: \w -> 数字、大小写字母以及下划线 -> [0-9a-zA-Z_]
	- console.log('0aZ_'.replace(/\b/, '.') // .0aZ_.
	- console.log('a+a'.replace(/\b/, '.')  // .a.+.a.
	- console.log('a a'.replace(/\b/, './)  // .a. .a.
- \B: 非单词边界
	- console.log('0aZ_'.replace(/\B/, '.') // 0.a.Z._
	- console.log('a+a'.replace(/\B/, '.')  // a+a
	- console.log('a a'.replace(/\B/, './)  // a a

---- 字符匹配位置

环视(?= | ?! | ?<=| ?<! )

  • ?= (瞻前)

    Untitled.png

  • ?! (否定顺序环视)

    Untitled 1.png

  • ?<= (顾后)

    Untitled 2.png

  • ?<! (否定逆序环视)

    Untitled 3.png

  • Case-1 「匹配一个位置,这个位置的后面需要是三个数字」

    Untitled 4.png

  • Case-2 「这个位置的后面是三个数字,然后就是字符串的结尾」

    Untitled 5.png

  • Case-3 - note: +作用于前面括号括起来的\d{3},表示至少需要有一个\d{3

    Untitled 6.png

    • /\B(?=(\d{3})+$/ 可以去掉第一个位置

?: (非捕获分组)

在正则表达式中,非捕获组 (?:) 是一种特殊的语法结构,用于指示匹配但不捕获匹配的内容。它是一种用于分组但不创建捕获组的方法。以下是一些非捕获组 (?:) 的案例介绍:

  1. 分组匹配但不捕获:

    const regex = /(?:ab)+/g;
    const input = 'ababab';
    const matches = input.match(regex);
    console.log(matches);  // 输出: ["ababab"]
    

    在这个例子中,(?:ab) 是一个非捕获组,+ 表示匹配前面的模式一次或多次。虽然使用了非捕获组,但仍会匹配整个字符串,但不会捕获其中的每个匹配项。

  2. 重复限定符应用在整个非捕获组上:

    const regex = /(?:\d{3}){2}/g;
    const input = '123456789';
    const matches = input.match(regex);
    console.log(matches);  // 输出: ["123456"]
    

    这个正则表达式 (?:\\d{3}){2} 匹配两个连续的三位数字并捕获为一个整体。非捕获组 (?:\\d{3}) 限制了重复次数,而不会在结果中创建捕获组。

  3. 配合其他正则表达式元字符使用:

    const regex = /(?:\bhttps?:\/\/)?(?:www\\.)?[a-zA-Z0-9-]+(?:\.[a-zA-Z]+){1,2}\b/g;
    const input = 'Visit my website at <https://www.example.com> or example.org';
    const matches = input.match(regex);
    console.log(matches);  // 输出: ["<https://www.example.com>", "example.org"]
    

    这个正则表达式可以匹配以 http://https:// 开头的网址,包括 www 子域名部分,以及一到两个域名后缀,但不捕获前面的协议部分。

通过使用非捕获组 (?:),你可以构建更精确的正则表达式模式,而不必在结果中包含用于捕获的额外组。