Regex 用逗号分隔的正则表达式唯一数字

Regex 用逗号分隔的正则表达式唯一数字,regex,Regex,我试图验证以逗号分隔的数字列表1-31的唯一性(不重复) i、 e 2,4,6,7,1为有效输入 2,2,6无效 2是有效的 2、无效 1,2,3,4,15,6,7,31有效 1,2,3,4,15,6,7,32无效 20,15,3 我试过了 ^(([0]?[1-9])|([1-2][0-9])|(3[01])(!([0]?[1-9])|([1-2][0-9])|(3[01])*,\\1(?([0]?[1-9])|([1-2][0-9])|(3[01])但它接受重复的数字 我完全同

我试图验证以逗号分隔的数字列表1-31的唯一性(不重复)

i、 e

  • 2,4,6,7,1为有效输入

  • 2,2,6无效

  • 2是有效的

  • 2、无效

  • 1,2,3,4,15,6,7,31有效

  • 1,2,3,4,15,6,7,32无效

  • 20,15,3

    我试过了
    ^(([0]?[1-9])|([1-2][0-9])|(3[01])(!([0]?[1-9])|([1-2][0-9])|(3[01])*,\\1(?([0]?[1-9])|([1-2][0-9])|(3[01])
    但它接受重复的数字


我完全同意有比正则表达式更好的方法来寻找副本,但是如果你必须以正则表达式的形式来做,这里有一种方法(取决于你的正则表达式风格)

请参阅上的(我将其制作成多行并扩展,仅用于测试和可读性)

说明:

  • (?!.*\b(\d+)\b.*\b\1\b)
    是一种负前瞻,以确保没有重复项
  • (0?[1-9]|[12][0-9]|3[01])
    匹配第一个数字
  • (,(0?\d |[12][0-9]| 3[01])*
    匹配更多

注意:更新为使用单词边界-根据@sln的回答,我完全同意有比正则表达式更好的方法来查找重复项,但如果您必须以正则表达式的形式执行此操作,则有一种方法(取决于您的正则表达式风格)

请参阅上的(我将其制作成多行并扩展,仅用于测试和可读性)

说明:

  • (?!.*\b(\d+)\b.*\b\1\b)
    是一种负前瞻,以确保没有重复项
  • (0?[1-9]|[12][0-9]|3[01])
    匹配第一个数字
  • (,(0?\d |[12][0-9]| 3[01])*
    匹配更多

注意:已更新为使用单词边界-根据@sln的回答,对于超过1位的数字范围,只需添加单词边界即可
捕获组和反向引用。
这是一个完整的数字

这个特殊的是麻木范围1-31

 ^                                       # BOS
 (?!                                     # Validate no dups
      .* 
      (                                       # (1 start)
           \b 
           (?: [1-9] | [1-2] \d | 3 [0-1] )        # number range 1-31
           \b 
      )                                       # (1 end)
      .* 
      \b \1 \b 
 )
 (?: [1-9] | [1-2] \d | 3 [0-1] )        # Unrolled-loop, match 1 to many numb's
 (?:                                     # in the number range 1-31
      , 
      (?: [1-9] | [1-2] \d | 3 [0-1] )
 )*
 $                                       # EOS
var数据=[
'2,4,6,7,1',
'2,2,6',
'2,30,16,3',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(函数(str){
(str+'给出'+/^(?).*(\b(?[1-9]|[1-2]\d |[3[0-1])\b.*\b\1\b)(?:[1-9]|[1-2]\d |[3[0-1])(?:,(?:[1-9]|[1-2]\d |[3[0-1]))*$/。测试(str测试(str测试)+“
”;
});
对于超过1位的数字范围,只需添加单词边界即可
捕获组和反向引用。
这是一个完整的数字

这个特殊的是麻木范围1-31

 ^                                       # BOS
 (?!                                     # Validate no dups
      .* 
      (                                       # (1 start)
           \b 
           (?: [1-9] | [1-2] \d | 3 [0-1] )        # number range 1-31
           \b 
      )                                       # (1 end)
      .* 
      \b \1 \b 
 )
 (?: [1-9] | [1-2] \d | 3 [0-1] )        # Unrolled-loop, match 1 to many numb's
 (?:                                     # in the number range 1-31
      , 
      (?: [1-9] | [1-2] \d | 3 [0-1] )
 )*
 $                                       # EOS
var数据=[
'2,4,6,7,1',
'2,2,6',
'2,30,16,3',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(函数(str){
(str+'给出'+/^(?).*(\b(?[1-9]|[1-2]\d |[3[0-1])\b.*\b\1\b)(?:[1-9]|[1-2]\d |[3[0-1])(?:,(?:[1-9]|[1-2]\d |[3[0-1]))*$/。测试(str测试(str测试)+“
”;
})
我已经创建了一个可以实现这一点的模式

模式:
^((?!(\d+),[^\n]*\b\2\b)([1-9]\b |[1-2]\d |[3[0-1])(,(?1))?)$

A

简短的描述

  • ^
    -匹配行首
  • (?!(\d+,[^\n]*\b\2\b)
    -向前看以确保下一个数字不会重复
    • (\d+)
      -抓取下一个号码
    • ,[^\n]*
      -逗号后跟除新行以外的任何内容
    • \b\2\b
      -下一个数字再次重复
  • ([1-9]\b |[1-2]\d | 3[0-1])
    -检查1-31之间的下一个数字
    • [1-9]\b
      -检查单个数字。用于防止两位数匹配的边界
    • [1-2]\d
      -检查10-29
    • 3[0-1]
      -检查30,31
  • (,(?1))?)
    如果后跟逗号,则在主模式上递归,以检查下一个数字是否重复
  • -检查后接命令
  • (?1)
    -在主模式上递归
  • $
    -行末

更新:忘了检查1-31,我已经创建了一个可以执行此操作的模式

模式:
^((?!(\d+),[^\n]*\b\2\b)([1-9]\b |[1-2]\d |[3[0-1])(,(?1))?)$

A

简短的描述

  • ^
    -匹配行首
  • (?!(\d+,[^\n]*\b\2\b)
    -向前看以确保下一个数字不会重复
    • (\d+)
      -抓取下一个号码
    • ,[^\n]*
      -逗号后跟除新行以外的任何内容
    • \b\2\b
      -下一个数字再次重复
  • ([1-9]\b |[1-2]\d | 3[0-1])
    -检查1-31之间的下一个数字
    • [1-9]\b
      -检查单个数字。用于防止两位数匹配的边界
    • [1-2]\d
      -检查10-29
    • 3[0-1]
      -检查30,31
  • (,(?1))?)
    如果后跟逗号,则在主模式上递归,以检查下一个数字是否重复
  • -检查后接命令
  • (?1)
    -在主模式上递归
  • $
    -行末

更新:忘了检查1-31

为什么不按分隔符拆分数字列表,然后检查iterable对象中是否有重复的数字?列表中的数字是否固定,不能超过,在任何情况下,我都建议您将问题分解,而不是在1个正则表达式中完成所有操作:也许一个正则表达式可以验证逗号数字格式是否正确,然后在逗号上拆分,并通过使用哈希集循环来验证数字是否唯一这感觉就像拆分为一个列表,在那里执行操作会更好,不是很好地使用regex你的regex风格是什么?我不认为regex与这里有什么关系。您使用的编程语言是什么?为什么不先用分隔符拆分数字列表,然后用chec