Skip to content

正则

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp

定义

两种方式

js
const regexp = /pattern/gim;
js
const regexp = new RegExp("pattern", "flags");

/.../ 是完全静态的。

修饰符

i 搜索时,不区分大小写

g 返回所有的匹配项目。默认只返回第一个。

m 多行模式,只影响 ^$ 的行为。

m

多行是以 换行符(\n)为分界的

js
`1st place: Winnie
2nd place: Piglet
3rd place: Eeyore`.match(/^\d/gm); // ['1', '2', '3']

s dotall 模式,允许.匹配换行符(\n)

u 开启完整的 Unicode 支持

y 粘滞(Sticky)模式

y

配合 RegExp.lastIndex 和 RegExp.exec 使用。

js
regexp.lastIndex; // 0

regexp.exec("let varName"); // [ 'let', index: 0, input: 'let varName', groups: undefined ]

regexp.lastIndex; // 3

默认情况下,会在 lastIndex 处开始查询。

y 的情况下,会在指定 index 精准查询。

字符类(Character classes)

\d 是 digit,数字,0-9

\s 是 space 空格,制表符\t,换行\n,其他稀有字符(如:\v\f\r

\w 是 word,单字,拉丁字母(A-Za-z),数字,下划线(_)。

每个字符类,都有一个“反向类”

\D 非数字:除 \d 以外的任何字符,例如字母。

\S 非空格符号:除 \s 以外的任何字符,例如字母。

\W 非单字字符:除 \w 以外的任何字符,例如非拉丁字母或空格。

. / 点

“除换行符之外的任何字符”

带有修饰符 s 时候,可以换行符的(\n),也就变成了匹配任意字符

^$

^ 匹配 开始

$ 匹配 结尾

js
/^Mary/.test("Mary had a little lamb"); // true

/snow$/.test("it's fleece was white as snow"); // true

startsWith/endsWith 也可以完成这些工作,正则是用于更为复杂的工作中。

\b / 词边界

🐳 需要运用理解

检查字符串中的位置是否是词边界。

词边界:

  • 在 string 开头,如果第一个字符 \w
  • 在 string 两个字符之间,其中一个是\w,另一个不是
  • 在 string 末尾,如果最后一个字符是 \w

\ / 转义

常见的特殊字符:[ ] { } ( ) \ ^ $ . | ? * +

/ 并不是,但是 js 使用了它,所以也需要转义

注意

/\d/ 在 new RegExp 中需要为("\\d")

[...] / 集合

https://www.yuque.com/qinsjs/jsinfo/lrlgc836nyefl44h

“搜索给定字符中的任意一个”,又称 集合。

虽然集合中可能有多个字符,但只会匹配 一个

集合中的^

这个 ^ 不是开始,是在集合内的,标识排除。

[^aeyo],匹配除了 'a'、'e'、'y' 或 'o' 之外的 任 何 字 符。

{n}, +, *, ? / 量词

量词是很常用的,它们是构成复杂正则表达式的主要“模块”。

{n},如:{3,5},匹配 3-5 个
n 可以省略第一个值,即 {3,}。此时为 大于等于 3。

+ {1,} “一个或多个“

? {0,1} “零个或一个”

* {0,} “零个及以上”

贪婪模式 与 惰性模式

https://www.yuque.com/qinsjs/jsinfo/brqgqc9x24kdmo9v

贪婪模式(默认)。对于字符串中的每一个位置,尝试匹配。

js
'a "witch" and her "broom" is one'.match(/".+"/g);

// ['"witch" and her "broom"']

惰性模式。“重复最少的次数” 在 量词 后添加一个问号? 来启用。

  • *变为*?
  • +变为+?
  • ?变为??
js
'a "witch" and her "broom" is one'.match(/".+?"/g);

// (2) ['"witch"', '"broom"']

capturing group / 捕获组

用括号括起来,称为“捕获组(capturing group)”

特点:

  • 与量词组合,视为一个整体
  • 组的结果会单独呈现

/go+/匹配:gooo、goooooooo
/(go)+/匹配:gogo、gogogo、gogogogo

组的返回,会带有多个数据。如果嵌套,会使一层一层拨开。如果可选组无匹配,会使用 undefined 占位。

需要每个匹配的详细信息,使用 API matchAll

组命名

如:/(?<name>(go)+)/

backreferences

引用一个 。语法为 \n

n 是组号。

js
`"she's the one"`.match(/['"](.*?)['"]/g);

// [`"she'`];

最终结果是 "she'

js
`"she's the one"`.match(/(['"])(.*?)\1/g);

引用名称

因为组可以命名,所以也就可以引用命名

js
`He said: "She's the one!".` //
  .match(
    /(?<quote>['"])(.*?)\k<quote>/g
    //
  );

| / 或

js
let regexp = /html|php|css|java(script)?/gi;

let str = "First HTML appeared, then CSS, then JavaScript";

str.match(regexp); // 'HTML', 'CSS', 'JavaScript'

[] 只能使用 \w ,而 | 可以使用表达式

先行断言

🐳 原文为 先瞻断言,为了好记,我使用 先行断言。

X(?=Y): 仅在后面是 Y 时匹配 X
X(?!Y): 搜索 X,但前提是后面没有 Y

非 V8 引擎的浏览器不支持后瞻断言

(?<=Y)X: 匹配 X,仅在前面是 Y 的情况下 (?<!Y)X: 匹配 X,仅在前面不是 Y 的情况下