正则表达式作为前端开发人员必不可少的工具,一直以来都是前端技术栈中重要的一环。随着 JavaScript 的发展,正则表达式的应用范围也越来越广泛,新的正则表达式特性也不断涌现。其中 ES9 的 Lookbehind 前瞻零宽断言、后顾零宽断言就是一个相当有趣的新特性。
什么是 Lookbehind 前瞻零宽断言、后顾零宽断言
在介绍 Lookbehind 前瞻零宽断言、后顾零宽断言之前,我们先来了解一下正则表达式中的零宽断言。
零宽断言是指一类匹配模式,它匹配内容的位置而非内容本身。它们并不消耗输入的字符串,也不会在匹配结果中出现。零宽断言有四种:先行断言、后行断言、先行否定断言、后行否定断言。
Lookbehind 是后行断言的一种,可用来检查目标字符串的前面是否匹配某个固定的模式。而 Lookahead 则为先行断言,用于检查目标字符串的后面是否匹配某个固定的模式。
在 ES9 中,Lookbehind 前瞻零宽断言、后顾零宽断言新增了对 Lookbehind 后行断言的支持。之前,JavaScript 没有后行断言。不过,借助于这个新增特性,我们就可以在一个模式的后面添加一个断言,这样模式只有在这个断言为真的情况下才会匹配。
Lookbehind 前瞻零宽断言的语法
Lookbehind 前瞻零宽断言的语法为:
/(?<=pattern)match/
其中 /
是正则表达式的开头和结尾,pattern
是要检查的模式,match
是要进行匹配的子字符串。
Lookbehind 前瞻零宽断言的作用是仅匹配出现在 pattern
之后的 match
,而不匹配 pattern
,pattern
只是作为匹配前提条件。
下面是一个实例,用 Lookbehind 前瞻零宽断言匹配字符串中符合条件的子字符串:
let str = "Hello World"; let pattern = /(?<=Hello\s)World/; let match = str.match(pattern); console.log(match[0]);
输出结果为:
World
在上面的代码中,我们通过 Lookbehind 前瞻零宽断言 /(?<=Hello\s)World/
匹配字符串 Hello World
中符合条件的字符串 World
。
Lookbehind 前瞻零宽断言的应用举例
1. 匹配带前缀的样式类名
有时候我们需要使用 JavaScript 操作 DOM 元素,比如为元素添加或删除某个样式类。这就需要判断某个 DOM 元素是否包含某个样式类名。
假如有一个样式类名叫 my-
,我们需要通过正则表达式匹配所有具有该前缀的样式类名,可以使用 Lookbehind 前瞻零宽断言来实现:
// 匹配所有具有 my- 前缀的样式类名 let pattern = /(?<=\b)my-\w+/g; let str = "my-class your-class their-class my-other-class"; let match = str.match(pattern); console.log(match);
输出结果为:
['my-class', 'my-other-class'];
2. 匹配日期 yyyy-mm-dd 格式
在处理日期格式时,我们经常需要从一个大字符串中匹配符合 yyyy-mm-dd 格式的日期字符串。这时可以使用 Lookbehind 前瞻零宽断言:
// 匹配 yyyy-mm-dd 格式的日期字符串 let pattern = /(?<=^|\D)(\d{4})-(\d{2})-(\d{2})(?=$|\D)/g; let str = "The date is 2020-10-19"; let match = str.match(pattern); console.log(match);
输出结果为:
['2020-10-19'];
在上面的代码中,我们使用 Lookbehind 前瞻零宽断言 /(?<=^|\D)
和后顾零宽断言 /(?=$|\D)/
匹配日期字符串。
(?<=^|\D)
用于匹配日期字符串的前面(^
表示字符串开头,\D
表示非数字字符),而 (?=$|\D)
用于匹配日期字符串的后面($
表示字符串结尾,\D
表示非数字字符)。
Lookahead 后行断言的语法
Lookahead 后行断言的语法为:
/(?<!pattern)match/
其中 /
是正则表达式的开头和结尾,pattern
是要检查的模式,match
是要进行匹配的子字符串。
Lookahead 后行断言的作用是仅匹配出现在 pattern
之前的 match
,而不匹配 pattern
,pattern
只是作为匹配前提条件。
下面是一个实例,用 Lookahead 后行断言匹配字符串中符合条件的子字符串:
let str = "Hello World"; let pattern = /World(?<!Hello\s)/; let match = str.match(pattern); console.log(match[0]);
输出结果为:
World
在上面的代码中,我们通过 Lookahead 后行断言 /(?!Hello\s)World/
匹配字符串 Hello World
中符合条件的字符串 World
。
Lookahead 后行断言的应用举例
1. 匹配出现在 * 前面但不是链接的单词
假如有一个字符串,里面包含一些文本。文本中有些单词出现在 *
号前面,表示这是一些注释或者高亮显示的文字,而其他单词并不在 *
号的前面,表示这些单词是与 *
号无关的其他内容。现在我们需要通过正则表达式匹配所有出现在 *
号前面但不是链接的单词,可以使用 Lookahead 后行断言来实现:
// 匹配出现在 * 前面但不是链接的单词 let pattern = /(?<=\*)\b\w+\b(?!\))/g; let str = "* javascript is great and * jQuery is also great but not as great as javascript (https://www.example.com) *"; let match = str.match(pattern); console.log(match);
输出结果为:
['javascript', 'great', 'also', 'great', 'but', 'not', 'as', 'great', 'as', 'javascript'];
在上面的代码中,我们使用 Lookahead 后行断言 /(?!\))/
排除链接,只匹配出现在 *
号前面但不是链接的单词。
2. 匹配 .com 顶级域名
假如我们需要从一段文本中匹配出现在字符串 http://example.com
中的 .com
顶级域名,可以使用 Lookahead 后行断言来实现:
// 匹配出现在 http://example.com 中的 .com 顶级域名 let pattern = /(?<=http:\/\/\w+\.)com/g; let str = "http://example.com is a great website"; let match = str.match(pattern); console.log(match[0]);
输出结果为:
.com
在上面的代码中,我们使用 Lookahead 后行断言 /(?<=http:\/\/\w+\.)com/
匹配出现在字符串 http://example.com
中的 .com
顶级域名。
总结
Lookbehind 前瞻零宽断言、后顾零宽断言是 JavaScript 正则表达式中的一个有趣的新特性,它们可以让我们编写更加简洁、高效、灵活的正则表达式。在实际的开发过程中,合理运用 Lookbehind 前瞻零宽断言、后顾零宽断言可以提升代码的质量和效率,让我们更加专注于业务逻辑,提高开发效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a2b8a048841e9894f3041a