JS 正则表达式练习(FCC摘录)

本文最后更新于 2021年4月4日 晚上

这个是跟着 FCC 中 JS 的正则表达式习题练习时候的记录.

正则表达式习题

  1. 写表达式的语法是这样的: /表达式/, 其结果是生成一个正则表达式对象, 在该对象上即可调用若干方法进行对应操作.

  2. 默认情况下是大小写敏感的, 比如搜索 Hellohello, 可能出现不同结果.

  3. 在正则表达式中可以使用 | 操作符, 比如 /a|b/ 表示找 "a""b".

  4. 在表达式尾部的 / 后面可以接选项, 如果需要忽略大小写, 则在尾部追加 i, 比如 /dog/i.

  5. String 对象提供了一个 match 方法, 可以直接在该方法中传入表达式, 返回的是搜索结果数组:

1
2
const occ = 'Hello World'.match(/o/i);
console.log(occ.length); // 输出 1
  1. 如果没有指定参数, 则默认只搜索最先找到的一个. 如果想搜索多个, 则可以使用 g 参数:
1
2
const occ = 'Hello World'.match(/o/ig);
console.log(occ.length); // 输出 2
  1. 使用 . 来匹配任意字符:
1
2
const occ = 'Hello World'.match(/l./ig);
console.log(occ); // 输出 [ 'll', 'ld' ]

可以看到这里实际没有找完, 因为 lo 没有被找到.

  1. 除了使用 . 来匹配外, 还可以使用 [] 来包含需要的字符:
1
2
const occ = 'Hello World'.match(/l[lod]/ig);
console.log(occ); // 输出 [ 'll', 'ld' ]

可见, 仍然没有在第一个单词中找到 lo, 即使前面指定过找 lo字符串(/l[lod]/).

  1. 除了列举, 还可以使用 - 来指定范围内的字符:
1
2
const occ = 'Hello World'.match(/l[a-p]/ig);
console.log(occ); // 输出 [ 'll', 'ld' ]
  1. 也可以列举数字:
1
2
const occ = 'Hello World 123456'.match(/[a-z0-9]/ig);
console.log(occ); // 输出中会包含字符串中除了空格外的所有字符
  1. 上述都是在将自己想要的字符进行列举, 而如果想列举自己不想要的字符, 则可以在模式开头添加一个 ^:
1
2
const occ = 'Hello World 123456 I hava a dream'.match(/[^a-p0-9]/ig);
console.log(occ); // 输出 [ ' ', 'W', 'r', ' ', ' ', ' ', 'v', ' ', ' ', 'r' ]

即会去找除了 0 到 9 数字, 以及 a 到 p 字母外的任意字符, 比如空格.

  1. 使用 + (一个或多个)来指定查找字符或重复出现的字符:
1
2
const occ = 'Hello World'.match(/l+/ig);
console.log(occ); // 输出 [ 'll', 'l' ]
  1. 使用 * (0 个或多个) 来匹配重复字符:
1
2
const occ = 'Heello World, and he says gotohell.'.match(/h*e/ig);
console.log(occ); // 输出: [ 'He', 'e', 'he', 'he' ]

上面的正则表达式含义就是找 0 到 多个 h 接一个 e 的情况, 忽略大小写和全局查找.

  1. 如果想要找一段文本, 中间是任意字符, 这样叫贪心查找, 即总是努力寻找到最长的字符串匹配值:
1
2
const occ = 'Heoello World, and he says gotohell.'.match(/h[a-z]*o/ig);
console.log(occ); // 输出 [ 'Heoello' ]

可以看到搜索时并没有输出 Heo, 而是输出的更长的 Heoello

  1. 和贪心查找相对的就是懒查找, 在贪心查找的 * 后面添加一个 ? 即可, 它就去找能匹配的最短字符串:
1
2
const occ = 'Heoello World, and he says gotohell.'.match(/h[a-z]*?o/ig);
console.log(occ); // 输出 [ 'Heo' ]
  1. 前面看到, 如果 ^ 用在集合 [] 内, 表示排除. 而如果是用在顶层, 则表示字符串开头:
1
2
const occ = 'Marray says "I\'m Marray".'.match(/^Marray/ig);
console.log(occ); // 输出 [ 'Marray' ]

可见只会搜索到开头的那个 Marray.

  1. 有开头就有结尾, 字符串结尾使用 $ 表示:
1
2
const occ = 'Hello World and welcome to our new world'.match(/World$/ig);
console.log(occ); // 输出 [ 'world' ]
  1. 有的时候通过字符集 [] 来枚举各种情况很费劲, 比如 [a-zA-Z0-9], 而 js 内提供了这类字符集的特殊写法:

比如使用 \w 来代表字母或数字:

1
2
const occ = 'Hello World1'.match(/W\w*/ig);
console.log(occ); // 输出 [ 'World1' ]

指定的是忽略大小写, 全局查找的, 以 W 开头的且包含 0 到多个字母和数字的连续字符的字符串, 通过 \w 来代表 [a-zA-Z0-9].

  1. 有表达 “字母或数字” 的符号, 就有表达 “非字母或数字” 的符号, 这个就是 \W:
1
2
const occ = 'Hello W@#$orld1'.match(/W\W*/ig);
console.log(occ); // 输出 [ 'W@#$' ]
  1. 匹配所有数字, 使用 \d (即[0-9]), 非数字使用 \D (即 [^0-9]).

  2. 使用 \s 代表空白字符, 可以认为它代表的是 [ \r\t\f\n\v], 即空格或回车换行等, 非空白就是 \S.

  3. 可以使用 {lower, upper} 这样的形式来指定匹配次数, 比如:

1
2
const occ = 'Hello W@#$orld1 H1 H12 H123 H123456'.match(/H\w{3,5}/ig);
console.log(occ); // 输出 [ 'Hello', 'H123', 'H12345' ]

找以 H 开头不区分大小写的连续字符串, 后面跟的连续字符串最小长度是 3, 最大长度是 5.

  1. 在使用匹配次数操作符的时候也可以不指定上界:
1
2
const occ = 'Hello W@#$orld1 H1 H12 H123 H123456'.match(/H\w{3,}/ig);
console.log(occ); // 输出 [ 'Hello', 'H123', 'H123456' ]
  1. 当然可以严格限制匹配的字符个数:
1
2
const occ = 'Hello W@#$orld1 H1 H12 H123 H123456'.match(/H\w{3}/ig);
console.log(occ); // 输出: [ 'Hell', 'H123', 'H123' ]
  1. 如果 ? 没有用在懒搜索中, 则表示的是 0 个或一个:
1
2
const occ = 'Hello W@#$orld1 H23 H12'.match(/H\w?/ig);
console.log(occ); // 输出 [ 'He', 'H2', 'H1' ]
  1. 在一个字符串中仅向前搜索而不产生对应模式的匹配结果, 则可以使用 LookAhead, 它有两种形式:
  • positive lookahead: will look to make sure the element in the search pattern is there, but won’t actually match it.

    语法是 (?=...), 其中 ... 位置就是想要判断的模式.

    1
    2
    const occ = 'Hello World'.match(/H(?=e)/ig);
    console.log(occ); // 输出 [ 'H' ]

    即匹配以 H 开头的, 如果 H 之后是 e, 则匹配成功, 相当于加一个条件, 但不将条件模式加入到匹配结果, 只看它在不在.

  • negative lookahead: will look to make sure the element in the search pattern is not there.

    1
    2
    const occ = 'Hello World'.match(/H(?!o)/ig);
    console.log(occ); // 输出 [ 'H' ]

    即匹配以 H 开头的, 且判断 H 后续是否包含有 o, 如果有则匹配失败, 否则匹配成功.

  1. 在写模式的时候有很多模式都是重复的, 如果复制粘贴一串来看肯定很长又不好看, 最好的办法还是使用 capture groups 来写可重用的模式, 实际语法就是 () 括起来, 在后面需要重复的时候只用指定类似 \1 即可, 其中 1 代表的是第一个 group:
1
2
const occ = "regex regex".match(/(\w+)\s\1/ig);
console.log(occ); // 输出 [ 'regex regex' ]
  1. 可以使用 $1 这样的语法来访问正则表达式搜索的结果:
1
2
const occ = "Hello World".replace(/(\w+)\s(\w+)/, '$2 $1');
console.log(occ); // 输出 World Hello
  1. 使用 trim 操作符移除字符串首尾的空白符:
1
2
const occ = "\r\n Hello World\r\n".trim();
console.log(occ); // 输出 "Hello World"

JS 正则表达式练习(FCC摘录)
https://blog.rayy.top/2019/01/27/2019-43-js-regular-expression-fcc/
作者
貘鸣
发布于
2019年1月27日
许可协议