【问题标题】:VIN Validation RegExVIN 验证正则表达式
【发布时间】:2015-05-19 00:26:14
【问题描述】:

我已经编写了一个基于 http://en.wikipedia.org/wiki/Vehicle_identification_number 的 VIN 验证 RegEx,但是当我尝试运行一些测试时,它不接受一些有效的 VIN 号码。

我的正则表达式:

^[A-HJ-NPR-Za-hj-npr-z\\d]{8}[\\dX][A-HJ-NPR-Za-hj-npr-z\\d]{2}\\d{6}$

VIN 号码不起作用:
1ftfw1et4bfc45903
WP0ZZZ99ZTS392124

VIN 号工作:
19uya31581l000000
1hwa31aa5ae006086

(我认为问题出现在末尾的数字上,维基百科听起来好像它只会以 6 个数字结尾,而一个不起作用但有效的数字只能以 5 结尾)

任何纠正此问题的帮助将不胜感激!

【问题讨论】:

  • 您提供的 Wikipedia 规范显示有许多不同样式的 VIN 号码。您要匹配哪些?
  • errrr 它必须检测到所有的 Vin 号码 :( 我以为我上面的那个是这样做的 :(

标签: regex validation


【解决方案1】:

我无法为您提供完美的 VIN 正则表达式,但我可以在您的 1ftfw1et4bfc45903 示例中解释为什么这个正则表达式失败:

^[A-HJ-NPR-Za-hj-npr-z\d]{8}[\dX][A-HJ-NPR-Za-hj-npr-z\d]{2}\d{6}$

解释:

  • ^[A-HJ-NPR-Za-hj-npr-z\d]{8}
    这允许 8 个字符,由任何数字和任何字母组成,除了 IOQ;它正确地找到了前 8 个字符:
    1ftfw1et
  • [\dX]
    这允许 1 个字符,可以是数字或大写 X;它正确地找到下一个字符:
    4
  • [A-HJ-NPR-Za-hj-npr-z\d]{2}
    这允许 2 个字符,由除 I、O 和 Q 之外的任何数字和任何字母组成;它正确地找到接下来的 2 个字符:
    bf
  • \d{6}$
    这恰好允许 6 位数字,这也是正则表达式失败的原因;因为最后 6 个字符并非全是数字:
    c45903

【讨论】:

    【解决方案2】:

    Dan 是正确的 - VIN 有一个校验和。你不能在正则表达式中使用它,所以你可以用正则表达式做的最好的事情就是把网络撒得太宽。我的意思是你的正则表达式将接受所有有效的 VIN,而且也能接受大约一万亿(粗略估计)非 VIN 17 个字符的字符串。

    如果您使用具有命名捕获组的语言,您也可以提取该数据。

    所以,如果你的目标是:

    • 不拒绝有效的 VIN(允许输入无效的 VIN) 然后使用 Fransisco 的答案,[A-HJ-NPR-Z0-9]{17}

    • 不拒绝有效的 VIN,并获取诸如型号年份、工厂代码等信息,然后使用它(注意,您必须使用一种可以支持命名捕获组的语言 - 我的脑海中浮现:Perl, Python,Elixir,几乎可以肯定是其他人,但不是 JS):/^(?<wmi>[A-HJ-NPR-Z\d]{3})(?<vds>[A-HJ-NPR-Z\d]{5})(?<check>[\dX])(?<vis>(?<year>[A-HJ-NPR-Z\d])(?<plant>[A-HJ-NPR-Z\d])(?<seq>[A-HJ-NPR-Z\d]{6}))$/ 名称在此答案的末尾定义。

    • 不拒绝有效 VIN,并防止部分但不是全部无效 VIN,您可以像 Pedro 一样获得具体信息。

    • 接受有效的 VIN:您需要编写代码(开个玩笑,GitHub exists)。

    捕获组名键:

    • wmi - 世界制造商标识符
    • vds - 车辆描述符部分
    • check - 校验位
    • vis - 车辆标识符部分
    • year - 车型年份
    • plant - 工厂代码
    • seq - 生产序列号

    【讨论】:

    【解决方案3】:

    这个正则表达式适用于验证美国 VIN,包括您描述的那个:

    [A-HJ-NPR-Z0-9]{17}

    记得用标志 i 使它不区分大小写

    来源:https://github.com/rfink/angular-vin

    【讨论】:

      【解决方案4】:

      VIN 应仅包含 A-Z0-9 字符,但不能包含 IOQ
      VIN的最后6个字符应该是一个数字
      VIN应该是17个字符长

      您没有指定您使用的是哪种语言,但以下正则表达式可用于通过php验证美国 VIN

      /^(?:([A-HJ-NPR-Z]){3}|\d{3})(?1){2}\d{2}(?:(?1)|\d)(?:\d|X)(?:(?1)+\d+|\d+(?1)+)\d{6}$/i
      

      【讨论】:

      • 最后 6 个字符并不总是像上面的例子那样是 6 个数字
      • 上述示例适用于美国。 VIN 的类型很多,您要匹配哪种类型?您发布的 wiki 页面上的所有 VINS 末尾都有 6 位数字。
      • 你可能想看看下面的问题stackoverflow.com/questions/26594504/…
      • 最后 6 个字符是数字,这不是普遍正确的en.wikipedia.org/wiki/Vehicle_identification_number
      • 如果车辆是 1981 年之前制造的,则 VIN 的范围可以从 11 到 17 个字符,因此并非在所有情况下都检查长度为 17。
      【解决方案5】:

      我觉得正则表达式不是理想的验证。 VIN 有一个内置的校验位。 https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/Check_digithttp://www.vsource.org/VFR-RVF_files/BVINcalc.htm

      我建议您使用它构建一个算法。 (Untested algorithm example)

      【讨论】:

        【解决方案6】:

        这应该可以,它来自 splunk 搜索,所以还有一些额外的排除项**

        (?i)(?<VIN>[A-Z0-9^IOQioq_]{11}\d{6})
        

        【讨论】:

          【解决方案7】:

          如果您有兴趣,NHTSA 网站提供了用于计算第 9 个字符校验和的方法。它还提供了许多其他有用的数据,例如在哪个位置允许哪些字符,或者如何确定第 10 个字符(如果是字母)是指 1999 年之前的车型年还是 2010 年之后的车型年。

          NHTSA VIN eCFR

          希望对您有所帮助。

          【讨论】:

          • 您可能需要编辑此链接以删除会话 ID (SID=e9e04d1dbab6285f7e27151cad41ed25)
          【解决方案8】:

          请使用这个正则表达式。它更短,适用于所有 VIN 类型

          (?=.*\d|[A-Z])(?=.*[A-Z])[A-Z0-9]{17}
          

          我把上面的公式改成了下面的新公式

          (?=.*\d|=.*[A-Z])(?=.*[A-Z])[A-Z0-9]{17}
          

          这个正则表达式考虑任何字母,但至少一位数,最多 17 个字符

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-05-07
            • 1970-01-01
            • 1970-01-01
            • 2012-04-19
            • 2021-02-24
            • 2014-02-25
            • 2019-06-21
            相关资源
            最近更新 更多