First, for your information, you can simplify your regex to:
^(?i)[-a-z0-9 ~!@#$%^()_'+={}[\]|:;,.?/]{0,45}$
Since you are using C#, do not yield to the temptation of replacing [0-9a-z_]
with \w
unless you use the ECMAScript option, as C# assumes your strings are utf-8 by default, and \w
will too happily match Arabic digits, Nepalese characters and so forth, which you might not want... Unless this is okay:
abcdᚠᚱᚩᚠᚢᚱტყაოსdᚉᚔమరמטᓂᕆᔭᕌसられま래도654۳۲١८৮੪૯୫୬१७੩௮௫౫೮൬൪๘໒໕២៧៦᠖
(But that's 60 chars, over your 45 limit anyway... Whew.)
More interestingly:
What was wrong before?
When you have a regex such as [^*][a-z]
(simplifying your earlier expression), the [^*]
matches exactly one character, then the [a-z]
matches exactly one other character (the next one). They do not work together to impose a condition on the next character. Each of them are character classes, and each character specifies the next character to be matched, subject to an optional quantifier (in your case, the {0,45}
Would this work?
On the surface, this might look like the ticket, but I do not recommend it:
^[^*]{0,45}$
Why not? This matches any character that is not an asterisk, zero to 45 times. That sounds good, but eligible characters would include tabs, new lines, and any glyph in any language... Probably not what you are looking for.