Reputation: 1943
Given a range of numbers say 1-30 , a user is allowed to select any number of values without repetition between 1 and 30,I am trying to write a regular expression to find out the valid and invalid inputs .
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");
}
For example :
4,78,6 is invalid
2,6,24 is valid
What should I change my regular expression as ?
Upvotes: 0
Views: 97
Reputation: 163372
You could do this without a regex, but as an answer to your question in your regex [1-3][1-1]
matches 11 or 21 or 31 so you match a repeating pattern of for example 31,1121,11.
If you want to do this using a regex, you could use a pattern (?:[1-9]|[12]\d|30)
to match a number 1 - 30 and then repeat that pattern 0+ times preceded by a comma.
If that format matches, use split and check if the number of items is equal to the distinct version.
For example:
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
See the C# demo | Regex demo
Upvotes: 0
Reputation: 56443
it would be more appropriate to use Linq to validate;
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);
or better create your own custom function.
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;
}
Upvotes: 1
Reputation: 8892
Regex is a text-processing tool to match pattern in regular languages. It is very weak when it comes to semantics. It cannot identify meaning in the given string. Like in your given condition, to conform to 1 <= x <= 30
condition, you need to have the knowledge of their numerical values.
So, you are using wrong tool. Regex can't help you here. Or even if you get a solution, that will be too complex, and will be too difficult to expand.
The better way is to Split
the string on comma, and then compare numbers.
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
Upvotes: 4
Reputation: 494
You don't need for regex for this job You can try this
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)
}
sorry it not tested code but can help
Upvotes: 1