bananasananas
bananasananas

Reputation: 31

Regular expression: Match a string that contains no more than three consecutive Bs (without using negative lookahead)

This is a simple question but I just recently started learning about regex.

I need to give a regex that describes all strings that contain no more than three consecutive Bs.

It should match:

sdBBdfsBBB

BfsBBBdsfBBB

It shouldn't match:

fsBBBBsfBB

BBBBBfsBBBsd

I am not allowed to use negative lookahead, only fundamental operations and shortcuts and I have no idea how to solve this... I know that the regex .*B{1,3}.* would match the strings that I want my regex to match but it would also match those I do not want my regex to match...

Upvotes: 3

Views: 903

Answers (3)

Nikos M.
Nikos M.

Reputation: 8325

how about providing proper negative matches before and after and repeat:

^((^|[^B]*?)B{1,3}($|[^B]+?))+?$

test example

Update 2: matches BBBxBBByBBB correctly

REGEX explanation:

  1. (^|[^B]*?) => match start of text or a possibly empty string of preceding non-B characters (non greedily)
  2. B{1,3} => match consecutive B up to 3 times
  3. ($|[^B]+?) => match end of text or successive non-B characters (non-greedily)
  4. Finaly ^(pattern)+?$ => match start of text, match inside pattern repeatedly (at least once), untill end of text

The updated regex matches ONLY the first 2 strings, the last 2 are not matched.

Upvotes: 1

6502
6502

Reputation: 114519

You can describe the expression as being a sequence of either a non-B or one to three Bs followed by a non-B or by the end of the string.

^([^B]|B{1,3}([^B]|$))*$
  • ^ begin of string
  • ( ... )* zero or more of...
    • [^B] something different from B
    • | or
    • B{1,3}([^B]|$) one to three Bs followed by end of string or something different
  • $ end of string

If you want to exclude empty string just change the * into a + (that means "one or more").

Upvotes: 1

The fourth bird
The fourth bird

Reputation: 163362

To not match empty strings, you could match either repeated sets of 1-3 times a B with at least any char except a B in between or match a string that ends with 1-3 times a B

^(?:[^B]*(?:B{1,3}[^B]+)+B{0,3}|[^B]*B{1,3})$
  • ^ Start of string
  • (?: Non capture group
    • [^B]* Match 0+ times any char except B
    • (?: Non capture group
      • B{1,3}[^B]+ Repeat 1+ times 1-3 B's and 1+ times any char except B
    • )+ Close group and repeat 1+ times
    • B{0,3} Match 0-3 B's at the end
    • | Or
    • [^B]*B{1,3} Match 0+ times any char except B and then 1-3 times a B
  • ) Close group
  • $ End of string

Regex demo

If empty string are allowed, the pattern could be shortened to

^(?:[^B]*(?:B{1,3}[^B]+)*B{0,3})$

Regex demo

Note that negated character class [^B] matches any char except a B and could possibly also match a newline. To not allow newlines to match, use [^B\r\n] or [^B\s] to exclude whitespace chars.

Upvotes: 1

Related Questions