andriusjon
andriusjon

Reputation: 33

Issue with a regex pattern in C#

I have an issue with regex pattern in C# programming language. My regex pattern doesn't seem to work the way it does on Regexr, I am getting matches even for values not empty or not in the list, where my regex is intended for a specific list of values and an empty string. Below is the piece of code which could demonstrate the essence of the issue:

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
        var pattern = "^(2|4|First|Fourth)?";
        var regex = new Regex(pattern);
        var empty = "";
        var number = "3";
        var yes = "yes";
        var str = "str";

        Console.WriteLine("empty " + regex.IsMatch(empty));
        Console.WriteLine("number " + regex.IsMatch(number));
        Console.WriteLine("yes " + regex.IsMatch(yes));
        Console.WriteLine("string " + regex.IsMatch(str));
    }
}

It matches str and 3 when it shouldn't. Maybe you could suggest some solution?

Upvotes: 1

Views: 127

Answers (2)

Johnny
Johnny

Reputation: 9509

If you want to match empty or multiple options(as you mentioned in one of the comments), there is the way to go:

"^(|2|4|First|Fourth)$"

It will match empty, "2", "4", "First" or "Fourth".


The problem with the pattern you have proposed is that ? makes whole group optional so it will match anything :).

Upvotes: 0

Michał Turczyn
Michał Turczyn

Reputation: 37337

Pattern (2|4|First|Fourth) will match 2 or 4 or First or Fourth, you are correct, ^ mathes beginning of the string (so called anchor), but what you are not aware of is ? operator, which means **match zero or one occurence of a pattern, so, since it's applied to whole(2|4|First|Fourth)` pattern, it will match every string.

You can think of this as: match my pattern anchored at the beginning of hte string, but match it zero or one time, so, also match just beginning of a string.

See in Demo, that every string is matched (it matches beginning of a string).

Just remove ? operator or replace it with $, which matches end of a string (if it's desired).

To allow also empty string use ^(2|4|First|Fourth|)$ - it will anchor the end of the string with $ (as mentioned above), also another possibility is added in your alternation, which will allow empt string to match.

Another demo

Upvotes: 2

Related Questions