给定一个范围为1到30的数字,允许用户选择任意数量的值,而不能在1到30之间重复,我试图编写一个正则表达式来找出有效和无效的输入。
var input = "1,12,30";
Regex regex = new Regex("([1-3][1-1],[1-3][1-1])+");
if(regex.IsMatch(input))
{
Console.WriteLine("Input is in correct format");
}
例如:
4,78,6无效
2,6,24有效
我应该将正则表达式更改为什么?
答案 0 :(得分:4)
Regex是一种文本处理工具,用于匹配常规语言中的模式。在语义方面,它非常薄弱。它无法识别给定字符串中的含义。像在给定条件下一样,要符合1 <= x <= 30
条件,您需要了解其数值。
因此,您使用的是错误的工具。正则表达式无法在这里为您提供帮助。甚至即使您找到解决方案,也将过于复杂,并且很难扩展。
更好的方法是用逗号Split
字符串,然后比较数字。
var numbers = input
.Split(',') // split to an enumerable of strings
.Select(int.Parse) // transform to an enumerable of numbers
.ToArray(); // Creates an array from a IEnumerable<int>
return numbers.All(x => x > 0 && x <= 30) // range check
&& numbers.Length == numbers.Distinct().Length; // uniqueness check
答案 1 :(得分:1)
使用Linq进行验证更合适;
var isValid = input.Split(",")
.GroupBy(s => s)
.Select(g => new { Num = int.Parse(g.Key), Count = g.Count() })
.All(e => e.Count == 1 && e.Num > 0 && e.Num < 31);
或者更好地创建自己的自定义函数。
static bool IsValid(string input)
{
var strings = input.Split(",");
if (strings.Any(n => int.Parse(n) <= 0 || int.Parse(n) >= 31)) return false;
return new HashSet<string>(strings).Count == strings.Length;
}
答案 2 :(得分:1)
您不需要正则表达式即可完成此工作 您可以尝试
List<int> inputs = new List<int>();
//make sure the number in range
if(input > 0 && input < 31){
//if there's another input would be added into list so make sure not equal the previous one
if(inputs.count() > 0){
if(input != inputs.Any()){
inputs.Add(input);
}
}
else{
inputs.Add(input)
}
对不起,它未经测试,但可以提供帮助
答案 3 :(得分:0)
您可以在不使用正则表达式的情况下执行此操作,但是作为正则表达式中问题的答案,[1-3][1-1]
匹配11或21或31,因此您匹配了例如31,1121,11的重复模式。
如果您想使用正则表达式来执行此操作,则可以使用模式(?:[1-9]|[12]\d|30)
来匹配数字1-30,然后将该模式重复0+次并以逗号开头。
如果该格式匹配,请使用split并检查项目数是否等于不同版本。
例如:
string pattern = @"^(?:[1-9]|[12]\d|30)(?:,(?:[1-9]|[12]\d|30))*$";
var input = "1,12,30";
List<String> a = input.Split(',').ToList();
Console.WriteLine(Regex.Match(input, pattern).Success && a.Count == a.Distinct().Count()); // True
请参见C# demo | Regex demo