RegEx Javascript - Only 0-2 spaces or hyphens in whole string?

Viewed 197

I have the following simple regex:
/^[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+$/

i would like to make it possible to have strings like "Blabla Bla bshfkhsf". But the whole string should not have more then 2 spaces or hyphens.

I know, that i can limit spaces with "\s{0,2}", but how do i place such limit in the regex, so that strings like above are possible and the limit applies to the whole string, not to a "single" character?

EDIT: May this be ok:

^[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+((\s)|(-))?[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+((\s)|(-))?[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+$

Is there any better way?

3 Answers

If you don't want to match spaces only, you can match the first part, then use the quantifier {0,2} to repeat the whole part again preceded by a character class [\s-] to match either a whitespace char or a hyphen.

If it should be a whitespace char only, you could use a mere \s (which could also match a newline)

Note that in your pattern, the whole alternation ((\s)|(-))? is optional so the minimum length of a single match would be 3 characters in that case. See this example.

You could update the pattern to

^[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+(?:[\s-][a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+){0,2}$

Explanation

  • ^ Start of string
  • [a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+ Match 1+ times any of the listed
  • (?: Non capture group
    • [\s-] Match either a whitspace char or -
    • [a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+ Match 1+ times any of the listed
  • ){0,2} Close the group and repeat it 0-2 times
  • $ End of string

See a regex demo

Instead of repeating the whole character class, you can just use lookahead to combine the conditions:

/^(?=[^\s-]*([\s-][^\s-]*){0,2}$)[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df\s-]+$/

Regex 101 demo. It's essentially two regexes in one:

(?=[^\s-]*([\s-][^\s-]*){0,2}$)

This part checks whether or not the whole string satisfies 'not more than 2 whitespace or - characters' rule.

[a-zA-Z\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df\s-]+$

This part checks whether or not the whole string satisfies 'only letters, whitespace and hyphens' rule. The point is, whole pattern matches only if both checks pass.

Parapharasing your requirement, you need to match a string that cannot have three or more spaces.

Use

/^(?!(?:\S*\s){3})[a-zA-Z\s\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+$/
  ^++++++++++++++^       ^^

So,

  1. \s is added to the expression so that it could match whitespace
  2. (?!(?:\S*\s){3}) ensures no three or more whitespace occurs in the string (there can be any non-whitespace characters in between thanks to \S*).

More things to consider

To disallow spaces at the start and end add more lookaheads

/^(?!\s)(?!.*\s$)(?!(?:\S*\s){3})[a-zA-Z\s\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+$/
  ^+++++++++++++^

To also disallow consecutive spaces

/^(?!\s)(?!.*\s$)(?!.*\s{2})(?!(?:\S*\s){3})[a-zA-Z\s\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00df]+$/
                 ^+++++++++^
Related