How to allow only one special character multiple times in a REGEX expression

Viewed 790

I am trying to create a REGEX expression that will only allow alphanumeric characters and one special character that can be used multiple times. The special characters that can be included are ()-_,.$. For example:
abc_def is valid
abc-def is valid
abc--def is valid
abc_-def is not valid

I tried to figure it out and came up with this: [a-zA-Z0-9]*[\\-_().,\\$]?[a-zA-Z0-9]* but that only allows the special character to appear once (so abc--def wouldn't be valid like I want it to). But if I change the ? to a * then multiple different special characters can be included in the string (so abc-_def would be valid but I don't want it to be). I tried some other stuff like: [[a-zA-Z0-9\\-]*[a-zA-Z0-9_]*...] for example (my idea was that this would read as (alphanumeric && '-') || (alphanumeric && '_') || ...) but I can't find anything that will work.

It is also worth noting that something like: abc-def-ghi-jkl-mno should be valid, so anything of the form [alphanumeric][specialcharacters][alphanumeric] won't work. Additionally, the string can start and end with the special character.

Is it possible to create a REGEX expression that will work the way I want it to? Or am I stuck writing my own function? Thanks :)

P.S. I'm using this in a Validators.pattern() for form control in angular 9 in case that makes a difference

1 Answers

^[a-zA-Z0-9]*([\(\)-_,\.\$])(?:\1*[a-zA-Z0-9]*)*$|^[a-zA-Z0-9]+$ will do your job

Regex Demo

Details:

^[a-zA-Z0-9]*([\(\)-_,\.\$]) : match any character until you see first special character, place it in group 1

(?:\1*[a-zA-Z0-9]*)*$ : match pattern starting with special character of group 1 and after that normal characters, as many as possible, until end of the string

^[a-zA-Z0-9]+$ : for special cases when there is no special character, e.g. abc

\1 is called back-reference, it will be the last matched group link to learn more

Related