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

JavaScript正则表达式:复杂的输入验证,javascript,regex,Javascript,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-最终目标。零件范围和/或系列和/或任意组合的序列号。请注意,在指定范围或在序列中的逗号之后

我正试图构造一个正则表达式来筛选有效的部件和/或序列号组合,并带有范围

有效的零件号是两个字母、三位数图案或/[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
-最终目标。零件范围和/或系列和/或任意组合的序列号。请注意,在指定范围或在序列中的逗号之后,空格是可选的。请注意,一系列零件号的两侧具有相同的两个字母组合(即ab123-ab239)

我已经绞尽脑汁想了两天了,没有比这个更好的了:

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


我的正则表达式Fu很弱。

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

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

如果一切都通过了,那么输入是正确的。

首先,
[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
。虽然这不太可能发生,但我添加了单词boundary(
\b
)来覆盖它。两个序列号/零件号/范围之间必须至少有一个非单词字符,
(?:,\s*)?
表示只能是逗号和可选空格。您的
[,]*
将允许任意数量的空格和/或逗号,或者根本不允许任何字符。

javascript可以进行字符串拆分,所以应该不会太糟糕。此外,代码的可读性更高,如果您的需求因某种原因发生变化,那么修改代码应该比修改正则表达式更容易。如果连字符两侧的两个字母组合相同,我认为您无法使用正则表达式进行检查,但我也不是正则表达式专家。我不相信在正则表达式中可以使用匹配范围。例如,尝试在regex中查找验证ip地址的代码。我从未见过一个有效的解决方案(检查小于255的数字似乎是不可能的。)太棒了!起初,我没有将组设置为非捕获,后来忘记将backreference更改为\1。我真的很喜欢你在这里的思考方式——将一个部件/序列与一个可选范围相匹配,而不是我所说的部件/序列/部件范围/序列范围路径+2到惊人之处。我确实需要在正则表达式中添加字符串的开头和结尾,以使其正常工作,但仍然很棒。再次感谢。