Javascript 用于验证以逗号分隔的唯一数字列表的正则表达式
我试图验证以逗号分隔的数字列表1-7的唯一性(不重复) i、 eJavascript 用于验证以逗号分隔的唯一数字列表的正则表达式,javascript,regex,Javascript,Regex,我试图验证以逗号分隔的数字列表1-7的唯一性(不重复) i、 e 2,4,6,7,1为有效输入 2,2,6无效 2有效 2,无效 1,2,3,4,5,6,7,8无效(仅7个数字) 我尝试了^[1-7](?:,[1-7])*$,但它接受重复的数字 var数据=[ '2,4,6,7,1', '2,2,6', '2', '2,', '1,2,3,2', '1,2,2,3', '1,2,3,4,5,6,7,8' ]; data.forEach(函数(str){ 编写(str+'给出'+/(?!(
为有效输入2,4,6,7,1
无效2,2,6
有效2
无效2,
无效(仅7个数字)1,2,3,4,5,6,7,8
^[1-7](?:,[1-7])*$
,但它接受重复的数字
var数据=[
'2,4,6,7,1',
'2,2,6',
'2',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(函数(str){
编写(str+'给出'+/(?!([1-7])(?:(?!\1.))\1^(?:^ |,)[1-7]){1,7}$/.test(str)+'
');
});代码>编辑:
修复了重复数字不是第一个数字时的错误
一种方法是:
^(?:(?:^|,)([1-7])(?=(?:,(?!\1)[1-7])*$))+$
它捕获一个数字,然后使用一个前瞻来确保它不会重复自身
^ # Start of line
(?: # Non capturing group
(?: # Non capturing group matching:
^ # Start of line
| # or
, # comma
) #
([1-7]) # Capture digit being between 1 and 7
(?= # Positive look-ahead
(?: # Non capturing group
, # Comma
(?!\1)[1-7] # Digit 1-7 **not** being the one captured earlier
)* # Repeat group any number of times
$ # Up to end of line
) # End of positive look-ahead
)+ # Repeat group (must be present at least once)
$ # End of line
var数据=[
'2,4,6,7,1',
'2,2,6',
'2',
'2,',
'1,2,3,4,5,6,7,8',
'1,2,3,3,6',
'3,1,5,1,8',
'3,2,1'
];
data.forEach(函数(str){
编写(str+'给出'+/^(?:(:^ |,)([1-7])(?=(?:,(?!\1)[1-7])*$)+$/.test(str)+'
');
});代码>正则表达式不适用于此。您应该将列表拆分为一个数组,然后尝试不同的条件:
函数有效(列表){
var arrList=list.split(“,”);
如果(arrList.length>7){//如果大于7,则存在重复项
返回false;
}
var temp={};
用于(ARR列表中的var i){
if(arrList[i]==“”)返回false;//如果元素为空,则无效
临时[arrList[i]]=“”;
}
如果(Object.keys(temp.length!==arrList.length){//如果它们的长度不同,则存在重复项
返回false;
}
返回true;
}
console.log(有效(“2,4,6,7,1”);//真的
console.log(有效(“2,2,6”);//假的
console.log(isValid(“2”));//真的
console.log(isValid(“2,”);//假的
console.log(有效(“1,2,3,4,5,6,7,8”);//假的
console.log(有效(“1,2,3”);//真的
console.log(isValid(“1,2,3,7,7”);//false
不需要正则表达式:
函数有效(a){
var s=新的集合(a);
s、 删除(“”);//对于挂起的逗号大小写,例如:“2,”
返回a.length<7&&a.length==s.size;
}
变量a='2,4,6,7,1'。拆分(',');
警报(有效(a));//真的
a='2,2,6'。拆分(',');
警报(有效(a));//假的
a='2'。拆分(',');
警报(有效(a));//真的
a='2',.split(',');
警报(有效(a));//假的
"1,2,3,4,5,6,7,8",;
警报(有效(a));//假的
你们非常接近
^ # BOS
(?! # Validate no dups
.*
( [1-7] ) # (1)
.*
\1
)
[1-7] # Unrolled-loop, match 1 to 7 numb's
(?:
,
[1-7]
){0,6}
$ # EOS
var数据=[
'2,4,6,7,1',
'2,2,6',
'2',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(函数(str){
write(str+'给出'+/^(?。*([1-7]).*\1)[1-7](?:,[1-7]){0,6}$/.test(str)+'
');
});代码>与其他评论员一样,我建议您使用正则表达式以外的其他方法来解决问题
我有一个解决方案,但它太长了,无法在这里作为有效答案(答案限制为30k个字符)。我的解决方案实际上是语言理论意义上的正则表达式,长度为60616个字符。这里我将向您展示我用来生成正则表达式的代码,它是用Python编写的,但很容易用您想要的任何语言进行翻译。我用一个较小的示例(仅使用数字1到3)确认了它在原则上是有效的:
以下是用于生成正则表达式的代码:
def build_regex(chars):
if len(chars) == 1:
return list(chars)[0]
return ('('
+
'|'.join('{}(,{})?'.format(c, build_regex(chars - {c})) for c in chars)
+
')')
可以这样称呼:
'^' + build_regex(set("1234567")) + "$"
概念如下:
- 为了匹配单个数字
a
,我们可以使用简单的正则表达式/a/
- 要匹配两个数字
a
和b
,我们可以匹配析取/(a(,b)| b(,a)/
- 类似地,为了匹配
n
数字,我们匹配所有元素的析取,每个元素后跟不包含该元素的sizen-1
子集的可选匹配
- 最后,我们将表达式包装在
^…$
中以匹配整个文本
为什么要使用正则表达式?你不能用逗号分开,然后检查重复的值吗?你的问题是一个问题。告诉我们您试图解决的问题,而不是寻求解决方案的帮助,这似乎不是正确的方法。您是否被迫使用正则表达式?因为编写一个验证输入的函数不会太难。是的,我需要正则表达式。谢谢你,你比我快,我写的是完全相同的解决方案!回答得很好,我不是这么问的。这是正确的,但我需要正则表达式。也谢谢你虽然我认为正则表达式不适合这个,但我认为这是非常有创意的,用户确实要求使用正则表达式+1酷,但这1,2,3,3,6是真的,但应该是fakeThanks,但我需要正则表达式。还有一个问题。是相同的情况,但在本例中是在1到31个数字范围内。请参阅添加到post中,使用1到31个数字范围。
'^' + build_regex(set("1234567")) + "$"