简体   繁体   中英

c# regex match set of characters in any order only once

I need to match any combination of characters in set, in any order, but not duplicate characters. The set is "m,s,b,r,e,l,f,t" and for example

msb - valid
mbs - valid
m - valid
mmft - not valid (duplicate m)
mxel - not valid (x is not in set)

I use this tester http://regexstorm.net/tester

This is closest but will not capture all order combinations

^(?:[m]{1})|(?:[n]{1})$

For example nm will not be captured.

Any help appreciated, thank you.

If only consecutive repetitions are not allowed (like in mmft ), use this regex

^(?!.*(.)\1)[msbrelft]+$

Demo: https://regex101.com/r/11pGQB/1

If any character recurrence is not allowed (like in mftm ), use this:

^(?!.*(.).*\1)[msbrelft]+$

Demo: https://regex101.com/r/q1bpMr/1

The key point in the both regexes is the recurrence checking lookbehind:

  • In the first case ( ^(?!.*(.)\\1) ) the match fails if there is a character immediately followed by itself ( (.)\\1 ).

  • In the second case ( ^(?!.*(.).*\\1) ) the match fails if there is a character that repeats after some other sequence ( (.).*\\1 ).

If you only want to know if the string is a match you can do something like:

private bool IsMatch(string str) {
    HashSet<char> set = new HashSet<char>("msbrelft"),
                  viewed = new HashSet<char>();

    foreach (var c in str) {
        if (!set.Contains(c)) return false;
        if (viewed.Contains(c)) return false;
        viewed.Add(c);
    }
    return true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM