Javascript 用于验证以逗号分隔的唯一数字列表的正则表达式

Javascript 用于验证以逗号分隔的唯一数字列表的正则表达式,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+'给出'+/(?!(

我试图验证以逗号分隔的数字列表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+'给出'+/(?!([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
    数字,我们匹配所有元素的析取,每个元素后跟不包含该元素的size
    n-1
    子集的可选匹配
  • 最后,我们将表达式包装在
    ^…$
    中以匹配整个文本

为什么要使用正则表达式?你不能用逗号分开,然后检查重复的值吗?你的问题是一个问题。告诉我们您试图解决的问题,而不是寻求解决方案的帮助,这似乎不是正确的方法。您是否被迫使用正则表达式?因为编写一个验证输入的函数不会太难。是的,我需要正则表达式。谢谢你,你比我快,我写的是完全相同的解决方案!回答得很好,我不是这么问的。这是正确的,但我需要正则表达式。也谢谢你虽然我认为正则表达式不适合这个,但我认为这是非常有创意的,用户确实要求使用正则表达式+1酷,但这1,2,3,3,6是真的,但应该是fakeThanks,但我需要正则表达式。还有一个问题。是相同的情况,但在本例中是在1到31个数字范围内。请参阅添加到post中,使用1到31个数字范围。
'^' + build_regex(set("1234567")) + "$"