user1400915
user1400915

Reputation: 1943

Regular expression for matching repeated number of values in .net

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

Answers (4)

The fourth bird
The fourth bird

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

Ousmane D.
Ousmane D.

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

Vadim Martynov
Vadim Martynov

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

Abdelrhman Elsaid
Abdelrhman Elsaid

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

Related Questions