• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

js 数字格式之正则表达式_js

javascript 搞代码 7年前 (2018-06-13) 237次浏览 已收录 0个评论

不过最近落叶给了我一个正则,让我豁然开朗,比我写的犀利多了,所以今天拿出来简单说一下(只说十进制部分的匹配)。

先看下我之前写的正则://d+(?:/./d+)?(?:[eE][+-]?/d+)?/./d+(?:[eE][+-]?/d+)?/
落叶在 jquery 中发现的正则: /(?:/d*/.)/d+(?:[eE][+-]?/d+)/ (ps: 我去掉了 [+-] 因为没必要匹配那个。。)
很明显犀利很多。

我的思路其实很简单,就是根据官方描述然后写了个臃肿不堪的正则。
在 MDN JavaScript Guide 的 Values, variables, and literals#Floating-point literals 一节中可以看到。
对于js数字格式的语法描述为 [(+-)][digits][.digits][(Ee)[(+-)]digits] (PS:这不是正则)
所以我就粗略的写了一个表达式 (?:/d+)?(?:/./d+)?(?:[eE][+-]?/d+)?
当时看着比较舒服,但是在测试中,我发现了严重的问题,能空匹配,简单说就是任何空字符串都能匹配成功。

这是一个严重的BUG,所以我把它拆分为两部分,修复了这个BUG,于是得到了上面那个臃肿的代码,没办法水平有限。

其实是我想的太简单了,我只是按照传统的想法写的正则,先匹配整数,然后匹配小数,最后匹配指数。。。

再看 jQuery 中的正则 /(?:/d*/.)/d+(?:[eE][+-]?/d+)/ 写的太霸气了。
他的思路是先匹配浮点数,然后匹配小数点后面的整数,接着匹配指数,同样是3部分,只是匹配顺序不同而已。
当然如果匹配不到浮点数,就回溯放弃匹配,直接匹配整数和指数部分。
这样就不需要拆分成两个表达式了。

我们做个测试,先去掉 试试,测试数据如下:

123
1.23
1.2e3
1.2e+3
1.2e-3
.123
.12e3
.12e+3
.12e-3

正则: /(?:/d*/.)/d+(?:[eE][+-]?/d+)/

js 数字格式之正则表达式_js

发现 123 没匹配到,后面的浮点型数据都可以正常匹配。
为什么会这样呢,因为 (?:/d*/.) 是必须匹配到 . 的,所以整数就无法匹配成功了。
(?:/d*/.) 则可以在匹配失败的情况下回溯然后发现第二个表达式是个空,就是不匹配了。
自然就让出位置给后面的 /d+ 进行匹配了,所以整数可以匹配成功。

js 数字格式之正则表达式_js

这个正则霸气在于利用最少的代码实现最优的性能,当然整数情况回溯是必须的,不过性能上也不会有多大的问题。

我们来看个测试吧:

var str1 = "123, 1.23, 1.2e3, 1.2e+3, 1.2e-3, .123, .12e3, .12e+3, .12e-3";
var str2 = "123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123";

var re1 = //d+(?:/./d+)?(?:[eE][+-]?/d+)?/./d+(?:[eE][+-]?/d+)?/g;
var re11= new RegExp(re1.source, "g");

var re2 = /(?:/d*/.)/d+(?:[eE][+-]?/d+)/g;
var re22= new RegExp(re2.source, "g");

console.log(
    str1.match(re1).toString() === str1.match(re22).toString(),
    str2.match(re1).toString() === str2.match(re22).toString()
);

test(str1, re1, "str1 re1")(str1, re11, "str1 re11")
    (str1, re2, "str1 re2")(str1, re22, "str1 re22");

test(str2, re1, "str2 re1")(str2, re11, "str2 re11")
    (str2, re2, "str2 re2")(str2, re22, "str2 re22");

function test(str, re, name) {
    console.time(name);
    for (var i=0; i<1e6; ++i) str1.match(re);
    console.timeEnd(name);
    return test;
}

js 数字格式之正则表达式_js
对浮点和整数进行100万次匹配测试,可以看到浮点数测试相差0.1秒,整数相差0.2秒。
这已经是非常小的性能差异了,有的垃圾正则,100万次测试可能会相差十几甚至几十秒呢。

http://www.gaodaima.com/30528.html

这么个小知识点让我开拓了眼界,其实只是写的少,看的少,所以一直都是井底蛙,技术这东西,必须多看,多想,多写才行。
好了今天的分享完毕,明天见。

欢迎大家阅读js 数字格式之正则表达式_js》,跪求各位点评,若觉得好的话请收藏本文,by 搞代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:js 数字格式之正则表达式_js

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址