我正在尝试验证逗号分隔的数字1-31列表唯一(不重复)。
即
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]))
但它正在接受重复的数字
答案 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