你不知道的正则表达式之断言

379 阅读3分钟

前言

今天在瞎搞 vue3 重构时用到了require.content,在使用require.content的时候用到了正则匹配文件路径的情景,于是重新回顾了一遍 JavaScript 正则匹配相关的内容。本次文章主要针对正则匹配的断言展开,面向在特殊情景下需要排除某个特定长度字段进行匹配。

基本概念

正则的断言离不开两个主要概念:

  • 前瞻
  • 后瞻

前瞻 有分为 正向前瞻 和 负向前瞻。通俗讲为,以特定字符为基准往后匹配特定字符(串)。

后瞻 有分为 正向后瞻 和 负向后瞻。通俗讲为,以特定字符为基准往前匹配特定字符(串)。

前瞻、后瞻一览表,如下:

表达式名称描述
(?=exp)正向前瞻匹配后面满足表达式 exp 的位置
(?!exp)负向前瞻匹配后面不满足(排除)表达式 exp 的位置
(?<=exp)正向后瞻匹配后面满足表达式 exp 的位置
(?<!exp)负向后瞻匹配后面不满足(排除)表达式 exp 的位置

通过上述表格基本可以理解前瞻与后瞻的用途,主要用于匹配字符的位置。当然可以根据自身需求来判断是匹配满足(排除)某字符后面的字符(串),还是满足(排除)某字符前面的字符(串)。

情景交融

基础案例

// 以Jy为基准往后看,是否紧跟着Lie字段
/Jy(?=Lie)/g.test('JyLie')
// 以Jy为基准往后看,是否不紧跟着Lie字段
/Jy(?!Lie)/g.test('JyLie')
// 以Jy为基准往前看,是否紧跟着Lie字段
/(?<=Lie)Jy/g.test('LieJy')
// 以Jy为基准往前看,是否不紧跟着Lie字段
/(?<!Lie)Jy/g.test('LieJy')

require.content 匹配文件

在 node.js 中常使用到 require.content动态获取文件,Frontender 在开发过程中也常有使用,如 vue.js 中常用 require.content来动态获取当前目录下的文件,免得每次手动引入的麻烦,于是一顿操作猛如虎~

/* 
目录结构:
|--languages
    |----en.ts 英文字段
    |----zh.ts 中文字段
    |----index.ts 使用require.content整合字段,本文将不需被引用
 */

export default function loadLanguages() {
  const files = require.content('./', false, /(?<!index)\.ts$/);
  const language = files.keys().reduce((acc, key) => {
    const name = key.replace(/(.*\/)*([_-\w]+)(\.ts)*$/, '$2') || '',
      message = files(key).default;
    acc[name] = message;
    return acc;
  }, {});
}
loadLanguages(); // 获取所有语言的字段

可见通过/(?<!index)\.ts$/即可排除index.ts的引用,؏؏☝ᖗ 乛 ◡ 乛 ᖘ☝؏؏

查找以某字符开头的字符串

/^(?=JyLie).*$/.test('JyLie, Haha'); // true

查找不以某字符开头的字符串

/^(?!JyLie).*$/.test('Haha,JyLie'); // true

查找以某字符结尾的字符串

/^.*(?<=JyLie)$/.test('Haha, JyLie'); // true

查找不以某字符结尾的字符串

/^.*(?<!JyLie)$/.test('JyLie, Haha'); // true

查找不包含某个字符的字符串

/^(?!.*JyLie).*$/.test('hahah, JyLie, Haha'); // false
/^(?!.*JyLie).*$/.test('JyLie, Haha'); // false
/^(?!.*JyLie).*$/.test('hahah, JyLie'); // false

查找指定字符之间不包含某个字符的字符串

/A((?!JyLie).)+A/.test('hahah, JyLie, Haha '); // false
/A((?!JyLie).)+A/.test('A hahah, JyLie, Haha A'); // false
/A((?!JyLie).)+A/.test('A hahah, LieJy, Haha A'); // true

结语

总的来讲,正则的断言就是要抓住以谁为基准对字符串做匹配,是以特定字符为基准往后匹配特定字符串呢,还是以特定字符为基准往前匹配特定字符串,搞清楚基准问题一切好办。

啊哈哈哈哈嗝,刚加了个班总结文章,一眨眼就到 8 点半,是该归巢洗洗睡啦~

相关文献