Vicky
Vicky

Reputation: 105

Checking input string for the invalid character(s) using regex

I have the following code snippet in which I am checking a name for invalid characters and false is returned as soon as user enters invalid character (allowed characters are defined in regex).

Issue is: This works fine as long as user enters invalid character at the end of the line but if user enters any invalid character in between the ItemName i.e. moving the cursor back somewhere in the middle of the ItemName then he is allowed to write invalid character i.e. true is returned while false should have been returned.

What mistake am I doing in defining the regex? Or any other mistake? Thanks

bool validName = true;
Regex regex = new Regex(@"[a-zA-Z0-9_-]+$");
if (regex.IsMatch(ItemName, 0) == false) validName = false;
if (!validName)
{
    return false;
}
else
{
    return true;
}

Please let me know if anything is not clear.

Edit: I changed my regex from (@"[a-zA-Z0-9_-]+$") to (@"^[a-zA-Z0-9_-]*$") and it worked. Is there any obvious mistake I am doing or this is the correct solution?

Upvotes: 3

Views: 27471

Answers (2)

RobH
RobH

Reputation: 3612

You need an anchor at the start of your regex "^[a-zA-Z0-9_-]+$")

Your Regex will encounter an invalid character, then start trying to match again at the next character (which succeeds).

Your regex as a worked example:

ItemName ="abc!def";
Regex regex = new Regex(@"[a-zA-Z0-9_-]+$"); // Not modified
var result = Regex.IsMatch(ItemName, 0);

First the regex will match as many of your character class as possible because + is greedy:

 *--- Start of match.
"abc!def"
    ^--- Regex engine matched up to here.

The next part of your pattern is the $ anchor, or end of string (in this context). This doesn't match with '!' so the Regex starts trying to match again at the next character.

It again takes as many of your character class as possible:

      *--- Start of match
 "abc!def"
         ^--- Regex engine here.

Again it checks whether the next character is the end of the string (which it is). Therefore, a match is found ('def') and IsMatch returns true.

By adding the ^ (start of string) anchor to the beginning, you stop this from happening.

FYI, your whole method can be shortened to:

Regex regex = new Regex(@"^[A-Z0-9_-]+$", RegexOptions.IgnoreCase);
return regex.IsMatch(ItemName);

Edit:

Or even just:

return Regex.IsMatch(ItemName, @"^[A-Z0-9_-]+$", RegexOptions.IgnoreCase);

Upvotes: 4

Yanshof
Yanshof

Reputation: 9926

change the regex that you are using to

  Regex regex = new Regex(@"[^.*?(?=[\^#%&$\*:<>\?/\{\|\}]).*$");

this will check the invalid char in your field

Upvotes: 2

Related Questions