Regex for matches 0 and 1 where consecutive 1s must be odd?

Viewed 482

I would like to write a regex that can match binary string where consecutive 1s must have odd length.

Examples: 1001110111 is accepted, and 10110111 is not accepted.

(1(11)*|0*)*

The best I came up with is the one above, which is not correct. This regex will match consecutive even 1s too. Any other ideas?

TIA

4 Answers

You may use this regex for this with a negative lookahead:

^(?!(?:[01]*0)?(?:1{2})+(?:0|$))[01]+$

RegEx Demo

RegEx Details:

  • (?!(?:[01]*0)?(?:1{2})+(?:0|$)): Expression to fail the match when you have even number of 1s in the expression anywhere. (?:1{2})+ matches a pair of 1s
  • (?:0|$) ensures pair of 1s is not followed by 1
  • (?:[01]*0)?: only allows presence of 0 or start just before 1s

  • [01]+: Match a string with 0 or 1 with one or more length

I think another option could be to match either only zeroes or match optional leading zeroes and repeat matching odd 1's followed by either 1+ zeroes or the end of the string.

^(?:(?:0*1(?:11)*(?:0+|$))+|0+)$
  • ^ Start of string
  • (?: Non capturing group
    • (?: Non capturing group
      • 0*1(?:11)* Match 0+ zeroes, 1 and repeat 0+ times 11
      • (?:0+|$) Match 1+ zeroes or assert end of string
    • )+ Close non capturing group and repeat 1+ times to not match empty strings
    • | Or
    • 0+ Match only zeroes
  • ) Close non capturing group
  • $ End of string

Regex demo

This should not need the complications of the lookaround solutions. The basic problem with your attempted solution is the 0* which can match zero 0s before the next group of 1s.

0*(1(11)*0+)*(1(11)*)?

This handles leading 0s. If you're not concerned about that you can remove the 0*.

The "meat" is the inner expression with the 0+. Odd groups of 1s delimited by one or more 0s.

Since those groups end with 0, we need an optional odd group of 1s at the end in case the string ends in 1.

Note that as all quantities above are optional, the above solution will also match an empty string. If you require at least one 1, it's a little more complicated:

0*1(11)*(0+1(11)*)*0*
Related