用于测试固定电话号码模式的最快方法

Xot*_*750 5 javascript regex jquery underscore.js lodash

因此,挑战在于我们正在尝试检测字符串是否与固定电话号码模式匹配,这是一个简单的字符串模式.

模式是:

ddd-ddd-dddd
Run Code Online (Sandbox Code Playgroud)

其中"d"代表十进制数字而减号代表自身," - "

当前用于测试的模式是,但如果感觉没有足够的模式来揭穿错误的格式,则可以增加.

"012-345-6789"
"0124-345-6789"
"012-3456-6789"
"012-345-67890"
"01a-345-6789"
"012-34B-6789"
"012-345-678C"
"012"
Run Code Online (Sandbox Code Playgroud)

我们的目标,我所寻求的答案,是找到执行以最快的速度返回的方法boolean,其中true意味着模式是好的,false意味着该模式是不好的.

这是我目前的解决方案

function matchesPattern(pattern) {
    if (pattern.length !== 12) {
        return false;
    }

    var i = 0,
        code;

    while (i < 12) {
        code = pattern.charCodeAt(i);

        if (i > 8 || i % 4 !== 3) {
            if (code < 48 || code > 57) {
                return false;
            }
        } else if (code !== 45) {
            return false;
        }

        i += 1;
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

它可以在jsfiddle上与测试模式一起使用

我有一个jsperf创建,我将添加进一步建议的方法,以便可以比较方法的执行速度,以确定哪个是最快的

您的方法可以是将在浏览器中执行的任何有效的JavaScript代码,如果您愿意,可以使用ECMA5并定位现代浏览器,或者使用跨浏览器标准,如果不在IE6上运行,则答案将被视为不正确例如.您也可以使用任何您想要的第三方库,即jquery,lodash,下划线等.最后的要求是代码必须不能在Chrome v25或Firefox v20上执行

我有什么不清楚的地方请随时发表评论,我会更新我的问题以澄清.

只有微优化才有区别的答案

如果工作正常并且已添加到性能图表中,请不要更改您的答案.您可以提交1个以上的答案.

更新:好一周过去了,现在是时候宣布我将选择的答案.

从这个练习中学到了什么?

与手工构建的javascript例程相比,似乎正则表达式相对较慢,尽管对于大多数任务而言足够快.(至少对于小字符串模式)

没有使用任何第三方库,jquery,非核心等的解决方案,没有.并不是一个惊喜,但我有人可能已经尝试过.

展开的循环似乎仍然是王道.很多人说现在没有必要因为浏览器如此先进,但是这个测试仍然表明它们是最重要的.

我要感谢所有参与此问题的人,特别是那些实际提交测试代码的人.

vsz*_*rma 3

甚至比以前更快:

function tecjam5(pattern) {
    var c;
    return !(pattern.length != 12 ||
    !(((c=pattern.charCodeAt(2))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(4))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(11))>>1) == 28 || (c>>3) == 6) ||
    !(((c=pattern.charCodeAt(0))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(1))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(5))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(6))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(8))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(9))>>3) == 6 || (c>>1) == 28) ||
    !(((c=pattern.charCodeAt(10))>>1) == 28 || (c>>3) == 6) ||
    pattern.charAt(3) != '-' || pattern.charAt(7) != '-');
}
Run Code Online (Sandbox Code Playgroud)

(简而言之:每个 < 8 的数字只需要比较一次)