玩出花来的正则

前言

技术群里有人提问:请教一个正则 能够输入正负9位整数2位小数,小数能够不输入。因而,八仙过海,各显神通!前端

群里大佬的回答

很快,就有一位大佬发来一个他之前写的保留 2 位小数正则面试

// 这个正则是利用分组的方法,先匹配有没有减号,,而后匹配数字,而后匹配小数点,最后匹配2位小数

/^(\-)*(\d+)\.(\d{2})+.*$/
复制代码

明显这个大佬的正则达不到提问同窗的的需求,因而又有大佬给出了他的正则正则表达式

// 这个正则首先利用了?号的非贪婪模式匹配减号,而后匹配9位数,而后又用?号匹配是否有小数点

/^-?[0-9]{9}(\.[0-9]{2})?$/
复制代码

很快有人指出这个只能固定9位数,数字不能是固定的,大佬又修改了一版post

// 这个已经稍微能用了,能够匹配正负9位整数2位小数,小数能够不输入

/^-?[0-9]{1,9}(\.[0-9]{1,2})?$/
复制代码

急速(大概1~2秒钟),又有大佬指出,上面的正则能够匹配首位数为0的状况,通常来讲,数字的首位数不能为0性能

首位数字不能为0,那就加个判断就行了,因而正则改成优化

// 改成匹配首位数只能是1~9,不能为0

/^-?[1-9]{1}[0-9]{0,8}(\.[0-9]{1,2})?$/
复制代码

光速(几乎秒发),杠精(😀)提问:若是是是零点几的状况呢,或者就是整数0呢搜索引擎

大佬无奈给出spa

// 在分组和非贪婪匹配的基础上,又加上了与或非的概念,匹配整数,或者零点几的2位小数,或者是N位整数的2位小数

/^-?(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/
复制代码

可是这位大佬估计是没看清题目,没有限制整数的位数,因而又有大佬发出正则,逐渐复杂3d

// 根据前面大佬的正则修改了一下,匹配前面不能为0的2为小数,或者零点几的2位小数,或者0

/^(-?[1-9]{1}[0-9]{0,8}(\.[0-9]{1,2})?)|(0(\.[0-9]{1,2}))|(0)$/
复制代码

有大佬感受上面的正则都有点长,给出一个短的code

// 这个大佬喜欢使用集合,匹配加减号的集合,匹配任意数字的集合,匹配小数点的集合

/[+-]?[\d]{1,9}(\.[\d]{1,2})?/
复制代码

结合上面各位大佬的正则,有人给出

// 集合匹配加减号,匹配非零开头的2位小数,或者零开头的小数

/^[+-]?(([1-9][0-9]{0,8})|0)(\.[0-9]{1,2})?$/
复制代码

讨论到这里告一段落,我等萌新看的是瑟瑟发抖,彻底不敢说话。

tips:记得转string再用test判断,使用数字类型进入判断,最前面的0会自动给去掉

前端如何去写正则

在前端的项目中,会有许多须要正则的地方,那么如何去写一个正则呢?

有不少人说过正则不用去记,是的,大部分不用记。可是咱们如何去写正则仍是有必要去记一下的,这里我本人总结7条

  • 一、任何复杂的正则均可以用()号分组简单化
  • 二、| 这个符号是个好东西,或者或者或者,正则就出来了
  • 三、^ 开头,$ 结尾
  • 四、若是要这个正则匹配所有,屡次查找,就在最后面的 / 下面加个g,也就是 /g
  • 五、若是不区分大小写加个 i ,也就是 /i
  • 六、合理使用搜索引擎,仍是直接给一个搜索词吧:正则表达式速查表
  • 七、实在是本身写不出来,就搜索有没有写好的,或者去技术群里问大佬,要是没有大佬回复,就发个红包

正则表达式优化

当咱们会本身写正则以后,就要考虑一个问题了,如何写好一个高效率的正则,举个例子:

// 好比说咱们有一个字符串
const string = "TypeError: Cannot read property 'fundAbbrName' of undefined at Proxy.render (eval at";

// 咱们要截取TypeError: 到 (eval 之间的数据,使用正则
const reg = /(?:TypeError\:)(.*?)(?=\(eval)/

复制代码

使用RegexBuddy检测须要283步

修改一下:

const reg = /TypeError\:(.*?)\(e/
复制代码

使用RegexBuddy检测须要212步

再优化一下,改动一个单词,把 * 改为 +

const reg = /TypeError\:(.+?)\(e/
复制代码

步数减小了,如今须要209步

加一个限定条件 \s

const reg = /TypeError\:\s(.+?)\(e/
复制代码

又少了2步,如今只须要207步

改一下前面的限定条件

const reg = /\w+\:\s(.+?)\(e/
复制代码

进入200步之内了,199步

终极优化

const reg = /\w+\:(.+)\(/
复制代码

只需35步

经过上面的例子咱们能够得出一些正则优化方面的心得:

  • 当要捕获组的时候,使用非捕获型括号(?:),可是某些时候使用没必要要的(?:)反而会形成性能的浪费
  • 使用一些匹配规则可以提升正则的效率,好比说用 \w+ 替代 TypeError
  • 若是确认至少匹配1次,那么请用 + 号替代 * 号
  • 若是确认匹配的数量,请用 {n,m} 替代 + 号
  • 在大多数的状况下,限定条件多,会提升正则的效率
  • 尽可能使用非贪婪模式 ? ,可是,在某些状况下,不使用非贪婪模式反而效率会更快

最后

本人水平有限,又错误之处但愿各位大佬指出!

关于正则,我还写过一篇文章记一次面试题,正则表达式(?=a)是什么意思?,大佬们有空能够去看看。

相关文章
相关标签/搜索