1

We're trying to create a regular expression, which must match the following strings:

  • FOO-123123123123
  • FOO123123123123
  • FOO-123-123-123-123

It must satisfy the following conditions:

  • string must begin with FOO
  • symbols after foo may be only hyphens (optionally) and numbers
  • there can't be more than one hyphen in a row
  • the whole length of string can't be more than 50 symbols and less than 6

We've already came up with something like this

^FOO(-{0,1}[\d]+){6,50}$

but it seems like {6,50} sets limit of 50 not for total length of string, but for repeats of this capturing group

(-{0,1}[\d]+)

Can you please advice?

2 Answers2

2

You may use

^(?=.{6,50}$)FOO-?\d+(?:-\d+)*$

See the regex demo.

Details

  • ^ - start of string
  • (?=.{6,50}$) - the string length should be from 6 to 50 chars
  • FOO - a FOO substring
  • -? - an optional -
  • \d+ - 1+ digits
  • (?:-\d+)* - 0 or more repetitions of - and then 1+ digits
  • $ - end of string.

Note: \d may match more than ASCII digits, if you are worried about it compile the regex with RegexOptions.ECMAScript option, or replace \d with [0-9].

Also, ^(?=.{6,50}$)FOO(?:-?\d+)*$ will also work and is shorter, but it is bad parctice to use a single obligatory pattern with other optional patterns inside a quantified group. In this exact case, it is OK, but in other situations, following this logic may lead to catastrophic backtracking.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

You can use a lookahead for the specific character checking rules, and a "normal" expression for the overall length.

^FOO(?=(?:-?\d+)+$)[-\d]{3,47}$

The FOO is literal, and it must be the start of the string. The next block is a lookahead ((?=...)). This checks the subsequent string for the rule of no adjacent hyphens, and only digits. A lookahead is non-consuming, so after the lookahead completes, the engine is still looking at the end of "FOO". The last bit of the expression enforces that the only characters which follow "FOO" are hyphens or digits, and that there are a max of between 3 and 47, to account for the max of 6 - 50 (less the length of "FOO").

Kenneth K.
  • 2,987
  • 1
  • 23
  • 30