js 正则校验车架号VIN

发布于 2022-09-12 22:06:52 字数 237 浏览 19 评论 0

正则要求:

  1. 由大写字母和数字组成,长度17位;
  2. 字母不会出现O、Q、I三个字母;
  3. 第9位只能是【0-9】的数字和字母X;
  4. 第13-17位只能是数字;

根据百度、谷歌只搜搜到这个,还请各位大佬们赐教
现在只实现了1,2两个条件;如下:
let reg=/^[A-HJ-NPR-Z\d]{17}$/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

舂唻埖巳落 2022-09-19 22:06:52

根据规则一个个罗列出来不就是了?/^[A-HJ-NPR-Z\d]{8}[X\d][A-HJ-NPR-Z\d]{3}\d{5}$/

兮颜 2022-09-19 22:06:52

简单的是/^[A-HJ-NPR-Z\d]{8}[X\d][A-HJ-NPR-Z\d]{3}\d{5}$/这个规则,不过估计类似身份证号,里面应该还包括校验位,估计校验位就是第9位,所以完整判别估计不能只由规则式判定,还需要检测校验位。

检索到 https://baijiahao.baidu.com/s...
所以完整的还需要进一步进行判断。

这里有校验位计算方法 https://blog.csdn.net/shenhon...

var checkVIN=function(VIN){
    if(typeof(VIN)!='string') return false;
    if(VIN.length!=17) return false;
    VIN=VIN.toUpperCase();
    RE==/^[A-HJ-NPR-Z\d]{8}[X\d][A-HJ-NPR-Z\d]{3}\d{5}$/
    if(!RE.test(VIN)) return false;
    let cOT={
        '0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,
        '8':8,'9':9,'A':1,'B':2,'C':3,'D':4,'E':5,'F':6,
        'G':7,'H':8,'J':1,'K':2,'L':3,'M':4,'N':5,'P':7,
        'R':9,'S':2,'T':3,'U':4,'V':5,'W':6,'X':7,'Y':8,
        'Z':9
    };
    let xWT=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2]; // 因为第9位权重为0,所以原来是什么字符不影响结果,可以方便后面计算
    let sum=0;
    VINs=VIN.split('');
    for(let i=0;i<17;i++){
        sum=sum + cOT[ VINs[i] ] * xWT[i];
    }
    let cT=['0','1','2','3','4','5','6','7','8','9','X'];
    if( cT[ (sum%11) ] == VINs[8]) return true;
    return false;
}
画中仙 2022-09-19 22:06:52

@xdsnet 的回答已经很全面了,先用正则表达式快速检查,再做校验。我这里只是对代码做一个纯粹的技术探讨。

关于 cOT 的生成

手写太累,可以

const cOT = (() => {
    const entries = [
        "0123456789",
        " ABCDEFGH",
        " JKLMNOPQR",
        "  STUVWXYZ"
    ].flatMap(
        // Array.from 把字符串拆分成字符数组(主要是手写字符数组太累)
        // 根据字符位置生成 entry,比如 ['J', 1]
        // 完了进行 flat,把多组数组扁平化
        s => Array.from(s).map((c, i) => [c, i])
    );

    // 从 entires 生成对象,这个对象的键包含了空格、I、O 和 Q
    // 如果将上面的 IOQ 替换成空格,这里多的就只有空格
    const map = Object.fromEntries(entries);
    // 删除多余的键(其实不删也没关系,因为之前已经用正则已将这些字符排除掉了)
    return Array.from(" IOQ").reduce((m, c) => (delete m[c], m), map);
})();

这段代码只在初始化的时候执行一次,对效率没啥影响。如果还是想直接定义成常量,将上述代码的执行结果在控制台中用 JSON.stringify(cOT) 输出就是。

关于计算 SUM

效率并不如原生循环,只是把计算过程封装在一句话里。用 IIFE 也可以达到同样的效果。

const sum = Array.from(VIN)
    .map((c, i) => cOT[c] * xWT[i])
    .reduce((s, v) => s + v, 0);

关于 10 => 'X'

直接用数组很直接,关无毛病。

这是个时间换空间的写法(其实对于这点空间,没啥卵用),

const vcode = (mod => mod === 10 ? "X" : mod.toString())(sum % 11);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文