由逗号分隔的REGEX唯一编号

时间:2017-08-29 18:45:24

标签: regex

我正在尝试验证逗号分隔的数字1-31列表唯一(不重复)。

  • 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]))但它正在接受重复的数字

3 个答案:

答案 0 :(得分:3)

对于超过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 data = [
      '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(function(str) {
        document.write(str + ' gives ' + /^(?!.*(\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]))*$/.test(str) + '<br/>');
      });

答案 1 :(得分:2)

我完全同意有比正则表达式更好的方法来查找重复项,但如果你必须这样做正则表达式,这里有一种方法(取决于你的正则表达式的风格)。

请参阅regex101(我已将其设为多行并扩展,仅用于测试和可读性)。

^
(?!.*\b(\d+)\b.*\b\1\b)
(0?[1-9]|[12][0-9]|3[01])
(,(0?\d|[12][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的答案

答案 2 :(得分:2)

我创建了一个可以做到这一点的模式。

模式: import UIKit class ViewController: UIViewController { @IBOutlet var symbolView: SymbolTextLabel! var testString = "Understanding the concept of sales" var bulletSymbol = "\u{2022}" var fontsize: CGFloat= 18 override func viewDidLoad() { super.viewDidLoad() //First way // Dynamically creating SymbolTextLabel object let symbolTextLabel = SymbolTextLabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) symbolTextLabel.setText(text: testString, symbolCode: bulletSymbol) //setting text and symbol of text item symbolTextLabel.setFontSize(textSize: fontsize) // setting font size //symbolTextLabel.setSpacing(spacing: 5) // setting space between symbol and text self.view.addSubview(symbolTextLabel) //second way // from storyboard or interface builder symbolView.setText(text: testString, symbolCode: bulletSymbol) //setting text and symbol of text item symbolView.setFontSize(textSize: fontsize) // setting font size //symbolView.setSpacing(spacing: 5) // setting space between symbol and text } }

A demo

简短说明。

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

更新:忘记检查1-31