user1574598
user1574598

Reputation: 3881

C# MVC - Regex for integers with a single space or multiple spaces

I have some regex that limits an input field to integers with spaces:

[Required(ErrorMessage = "This field can not be left empty")]
[RegularExpression(@"^[\d\s]+$", ErrorMessage = "Please enter integers only with spaces")]
public string Numbers { get; set; }

I have been testing my app with single spaces, as any other junk typed in is detected via my validation.

However, I have just noticed validation does not pick up upon multiple spaces, which is sort of fine as I would like the user to be able to do this as well as single spaces, but I get issues with this line of code:

List<int> ints = new List<int>();
ints = numbers.TrimEnd().Split(' ').Select(s => int.Parse(s)).OrderBy(i => i).ToList();

Which splits all the numbers up, sorts them in ascending order, and puts them into a List<int> so it looks as though the Split function is accounting for one space only.

I'm not sure what the best solution is. It may be a case of limiting the regex to a single space, if so what would this be, or modifying the code above to accept multiple spaces?

Upvotes: 1

Views: 608

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626845

If you want to let users enter any amount of spaces anywhere in the string, you should consider changing \s with a space in the regex, or instead of a String.Split() use Regex.Split with \s+ pattern, to stay consistent with the input data, or plainly use regex to extract digit chunks with \d+.

So, use either

[RegularExpression(@"^[\d ]+$", ErrorMessage = "Please enter integers only with spaces")]
// ...
ints = numbers.TrimEnd().Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries).Select(s => int.Parse(s)).OrderBy(i => i).ToList();

Or keep the same regex as you have and grab all numbers with a regex:

ints = Regex.Matches(numbers, @"\d+").Cast<Match>().Select(s => int.Parse(s)).OrderBy(i => i).ToList();

If you plan to forbid entering more than 1 space between the numbers use either of

^ *[0-9]+(?: [0-9]+)* *$
^\s*\d+(?:\s\d+)*\s*$

See the regex demo.

Upvotes: 1

Related Questions