Regex conditionally does not return false on minimum underscores

I use this regex if the regex matches

 if (Regex.IsMatch(_familyname, @"(\S*_){3}\S"))

      

I tried to make sure that the word passing the test had at least this Word1_Word2_WORD3-maybe_Word4 (mark hyphens or spaces inside the word is not important) The regular expression (\ S * _) {3} \ S "also allows you to pass a word with two underscores . Is there a regex for only three underscores, and any word / character / character is allowed between those underscores? Oh, and it never ends or starts with an underscore. Also if test that the third alphanumeric string was everything capital, would be great. Actually I achieved all this using line splitting. However, I read the regex can it be faster? Also using .net 4.5.2

+3


source to share


3 answers


I had to add another regex to prevent users from creating a name with 4 underscores, this prevents the most common mistake, they can add more, so this is not the most elegant solution, besides, it may be slower than the solution that uses one regular expression. Thanx Mageos for a greedy, lazy and possessive tutorial, I used + to get fewer matches using regular storm, so I guess this is a faster method than I have before.



Regex.IsMatch (familyname, @ "(\ S +) {3} \ S")
& Amplifier ;! Regex.IsMatch (familyname, @ "(\ S +) {4} \ S")

0


source


Your expression is "greedy". Try the following:

if (Regex.IsMatch (familyname, @ "(\ S *?) {3} \ S"))



For more information see http://www.regular-expressions.info/possessive.html

0


source


You seem to want to check for a string that contains chunks of non-whitespace characters that have exactly 3 underscores. The main problem here is that it \S

matches underscore as well, so what you really want is the construct [^\s_]

- a negative character class that matches any char but whitespace and _

.

Then you have to make sure the _

origin for the match is not preceded by a non-whitespace (it also includes ), so you need a negative lookbehind (?<!\S)

.

And finally, since you need to make sure that there are no characters other than whitespace and underscore after the 4th chunk _

, you need to use atomic group (since there are no possessive quantifiers in .NET regex) prevent pattern-fallback [^\s_]+

(i.e. to check , isn't there _

after the last char matching [^\s_]

once).

Using

var res = Regex.IsMatch(str, @"(?<!\S)[^\s_]+(?>_[^\s_]+){3}(?!_)");

      

See regex demo

More details

  • (?<!\S)

    - negative lookbehind to make sure there are no char spaces left immediately to the left of the current location
  • [^\s_]+

    - 1 + characters other than spaces, and _

  • (?>

    - the beginning of the atomic group
    • _

      - underscore character
    • [^\s_]+

      - 1 + characters other than spaces, and _

  • ){3}

    - repeat the coincidence of the contents of the atomic group 3 times exactly
  • (?!_)

    - check once if there is _

    immediately to the right, and if it is there, we will not get a match, else will return a match.

Also, note that you can just split the string and then check if any of the chunks contains exactly 3 characters _

with a simple:

var str = "Word1_Word2_WORD3-maybe_Word4  Word1_Word2_WORD3 Word1_Word2_WORD3-maybe_Word4_Word5";
var res = str.Split().Any(s => s.Count(f => f == '_') == 3);
Console.WriteLine(res ? "Valid" : "Invalid");

      

See C # demo .

0


source







All Articles