0

I have an extension method like this;

public static bool IsBoolean(this string value)
{
    string lower = value.ToLower(CultureInfo.InvariantCulture);
    return new Regex("[true]|[false]|[0]|[1]", RegexOptions.Compiled).IsMatch(lower);
}

But this regex pattern fails when I give "fals" or "tru" as value. Such as;

[Theory(DisplayName = "IsBoolean")]
[InlineData("FALS")]
[InlineData("Fals")]
[InlineData("TRU")]
[InlineData("Tru")]
public void IsNotBoolean(string value)
{
    bool result = value.IsBoolean();
    Assert.False(result);
}

All these tests has been failed. Because result is true.
How is this possible? Is this regex pattern wrong ?

maccettura
  • 9,653
  • 3
  • 20
  • 28
Lost_In_Library
  • 2,783
  • 4
  • 33
  • 63
  • 4
    I think you want `^(true|false|[01])$`, possibly with `RegexOptions.IgnoreCase` option to ignore case. maccettura's advice below should work best though. – Wiktor Stribiżew May 18 '18 at 14:19
  • 6
    `[true]` matches any of the letters in the set. so `t` will be matched by `[true]`. – Chris May 18 '18 at 14:19
  • Possible duplicate of [Reference - What does this regex mean?](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean) – revo May 18 '18 at 14:23
  • 2
    Not an answer to your question, but please read up on what `RegexOptions.Compiled` is for, because this is definitely the wrong way to use it. –  May 18 '18 at 14:23
  • Thank you very much for comments. Yes, @WiktorStribiżew that's work, now I can check what is ^ and $ for. And bool.TryParse is better I know. Last think "hvd" I Thanks for point it out. Actually I refactored code to ask. Source code is different. – Lost_In_Library May 18 '18 at 14:32

1 Answers1

2

You want check if the string is any one of the following, ignoring case,

true
false
1
0

Then you just separate those strings with | and use that as the regex, and use the IgnoreCase option:

public static bool IsBoolean(this string value) {
    // note the ^ and $. They assert the start and end of the string.
    return new Regex("^(?:true|false|0|1)$", RegexOptions.IgnoreCase).IsMatch(value);
}

[] denotes a character class, so it will match any one character inside it. [abc] matches either a, b or c. Note the difference.

Sweeper
  • 145,870
  • 17
  • 129
  • 225
  • 1
    It was wrong even in the question, but `XtrueY` gives `true` :-) `^(true|false|0|1)$` would probably be better – xanatos May 18 '18 at 14:36
  • @xanatos Thanks for reminding me! I had been working with Java where I don't need those... – Sweeper May 18 '18 at 14:38