Skip to content
Advertisement

Regex match first character once, followed by repetitive matching until end

I’m trying to match characters that shouldn’t be allowed in a username string to then be replaced.

Anything outside this range should match first character [a-zA-Z] <– restricting the first character is causing problems and I don’t know how to fix it

And then match everything else outside this range [0-9a-zA-Z_.] <—- repeat until the end of the string

Matches:

  • /////hey/// <– first match /////, second match ///
  • [][123Bc_.// <– first match [][, second match //
  • (/abc <– should match (/
  • a2__./) <– should match /)

Non Matches:

  • a_____
  • b__…

Current regex

/^([^a-zA-Z])([^w.])*/
const regex = /^([^a-zA-Z])([^0-9a-zA-Z_.])*/;
'(/abc'.replace(regex, '') // => return expected abc
'/////hey///'.replace(regex, '') // => return expected "hey"

Advertisement

Answer

/^([^a-zA-Z])([^w.])*/

You can not do it this way, with negated character classes and the pattern anchored at the start. For example for your va2__./), this of course won’t match – because the first character is not in the disallowed range, so the whole expression doesn’t match.

Your allowed characters for the first position are a subset, of what you want to allow for “the rest” – so do that second part first, replace everything that does not match [0-9a-zA-Z_.] with an empty string, without anchoring the pattern at the beginning or end.
And then, in the result of that operation, replace any characters not matching [a-zA-Z] from the start. (So that second pattern does get anchored at the beginning, and you’ll want to use + as quantifier – because when you remove the first invalid character, the next one becomes the new first, and that one might still be invalid.)

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement