代码之家  ›  专栏  ›  技术社区  ›  Scott Baker

JavaScript正则表达式:复杂的输入验证

  •  2
  • Scott Baker  · 技术社区  · 14 年前

    我正在尝试构造一个regex来筛选有效的部分和/或序列号组合,并带有范围。

    有效的零件号是两个字母、三位数的模式或/[A-z]{2}\d{3}/

    i.e. aa123 or ZZ443 etc...
    

    有效的序列号是一个五位数的模式,或/\d{5}/

    13245 or 31234 and so on.
    

    那部分不是问题所在。我希望组合和范围也有效:

    12345, ab123,ab234-ab245, 12346 - 12349 -最终目标。范围 和/或 零件系列 和/或 任意组合的序列号。请注意,在指定范围或在序列中的逗号之后,空格是可选的。请注意,一系列零件号的两侧具有相同的两个字母组合(即。 ab型 123 -

    我已经苦思冥想了两天了,没有比这更好的表达方式了:

    /^(?:[A-z]{2}\d{3}[, ]*)|(?:\d{5}[, ]*)|(?:([A-z]{2})\d{3} ?- ?\4\d{3}[, ]*)|(?:\d{5} ?- ?\d{5}[, ]*)$/
    

    ...

    2 回复  |  直到 14 年前
        1
  •  1
  •   Alan Moore Chris Ballance    14 年前

    第一, [A-z] 这是错误的。除字母外,它还将匹配方括号、反斜杠、插入符号、下划线或反勾号——ASCII字符集中位于大写字母和小写字母之间的所有字符。你应该用其中一个 [A-Za-z] ,或 [A-Z] 使用不区分大小写选项。

    要匹配单个序列号或一系列序列号,请执行以下操作:

    /\d{5}(?:\s*-\s*\d{5})?/
    

    …对于零件号:

    /([A-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?/i
    

    在你的正则表达式中 \4 与第一部分编号中的字母匹配,但这只是第一部分 捕捉 所以你应该用 \1 .

    把这些放在一起匹配整个系列,你就有了

    /(?:\b(?:\d{5}(?:\s*-\s*\d{5})?|([A-Z]{2})\d{3}(?:\s*-\s*\1\d{3})?)(?:,\s*)?)+/i
    

    逗号必须是可选的,但这意味着正则表达式可能会错误地匹配如下序列 1234512345 12345ab123 \b )去掩盖它。两个序列号/零件号/范围之间必须至少有一个非单词字符,并且 (?:,\s*)? 表示只能是逗号和可选空格。你的 [, ]*

        2
  •  1
  •   Claudiu    14 年前

    你可能不想用正则表达式来做这些。如果您只有一个以逗号分隔的零件/序列号列表(可选范围),这可能会更简单:

    split input on commas
    for each input:
       if there is a dash:
           split on a dash, strip each element to remove whitespace
           make sure each side is a part or a serial number (can use 2 regexes here)
           if they're part numbers, make sure they start w/ the same two letters
       else:
           strip to remove whitespace, make sure is a valid part or serial number