程序员的知识教程库

网站首页 > 教程分享 正文

「正则表达式」六、正则表达式的构建(前端必懂 )

henian88 2024-08-16 17:34:01 教程分享 6 ℃ 0 评论

往期回顾

「正则表达式」 一、正则表达式字符匹配(前端必懂 )

「正则表达式」二、正则表达式位置匹配(前端必懂 )

「正则表达式」三、正则表达式括号的使用(前端必懂 )

「正则表达式」四、正则表达式回溯法原理(前端必懂 )

「正则表达式」五、正则表达式的拆分(前端必懂 )

正文内容

正则的构建需要考虑以下几点的平衡:

  • 匹配预期的字符串
  • 不匹配非预期的字符串
  • 可读性和可维护性
  • 效率

我们还需要考虑这么几个问题:

  • 是否需要使用正则

如能使用其他 API 简单快速解决问题就不需要使用正则:

  • 是否需要使用复杂正则

/(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/

将这个正则拆分成多个小块,如下:

1. 准确性

即需要匹配到预期目标,且不匹配非预期的目标。

  • 匹配固定电话

如需要匹配下面固定电话号码,可以分别写出对应正则:

055188888888 => /^0\d{2,3}[1-9]\d{6,7}$/
0551-88888888 => /^0\d{2,3}-[1-9]\d{6,7}$/
(0551)88888888 => /^0\d{2,3}-[1-9]\d{6,7}$/

然后合并:

let r = /^0\d{2,3}[1-9]\d{6,7}$|^0\d{2,3}-[1-9]\d{6,7}$|^\(0\d{2,3}\)[1-9]\d{6,7}$/

然后提取公共部分:

let r = /^(0\d{2,3}|0\d{2,3}-|\(0\d{2,3}\))[1-9]\d{6,7}$/

再优化:

let r = /^(0\d{2,3}-?|\(0\d{2,3}\))[1-9]\d{6,7}$/
  • 匹配浮点数

先确定,符号部分([+-])、整数部分(\d+)和小数部分(\.\d+)。

整理后:

2. 效率

正则表达式运行过程:

  1. 编译
  2. 设定起始位置
  3. 尝试匹配
  4. 若匹配失败则返回前一步重新匹配
  5. 返回匹配成功失败的结果

我们常常优化对 3 和 4 步进行优化:

  • 使用具体字符组替代通配符,消除回溯

如 /"[^"]*"/ 代替 /".*?"/。

  • 使用非捕获型分组

当不需要使用分组引用和反向引用时,此时可以使用非捕获分组。

如 /^[-]?(?:\d\.\d+|\d+|\.\d+)$/ 代替 /^[-]?(\d\.\d+|\d+|\.\d+)$/。

  • 独立出确定字符

加快判断是否匹配失败,进而加快移位的速度。

如 /aa*/ 代替 /a+/。

  • 提取分支公共部分

减少匹配过程中可消除的重复。

如 /^(?:abc|def)/ 代替 /^abc|^def/。

  • 减少分支的数量,缩小它们的范围

如 /rea?d/ 代替 /red|read/。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表