Regex match capture group multiple times

Viewed 786

I'd like to have a regex capture all instances of a pattern between two delimiters.

Simplified example to one character patterns (goal: capture all b between first x and last z):

bbxabbcbacbedbzbb
    ^^ ^  ^  ^  

should capture the 5 bs.

I tried .*x.*(b).*z.* which only captures the last b. (rubular)

1 Answers

Use

(?:x|(?<!\A)\G).*?\Kb(?=.*z)

See regex proof.

EXPLANATION

--------------------------------------------------------------------------------
  (?:                      group, but do not capture:
--------------------------------------------------------------------------------
    x                        'x'
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    (?<!                     look behind to see if there is not:
--------------------------------------------------------------------------------
      \A                       the beginning of the string
--------------------------------------------------------------------------------
    )                        end of look-behind
--------------------------------------------------------------------------------
    \G                       where the last m//g left off
--------------------------------------------------------------------------------
  )                        end of grouping
--------------------------------------------------------------------------------
  .*?                      any character except \n (0 or more times
                           (matching the least amount possible))
--------------------------------------------------------------------------------
  \K                       match reset operator (omits matched text)
--------------------------------------------------------------------------------
  b                        'b'
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    .*                       any character except line breaks (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    z                        'z'
--------------------------------------------------------------------------------
  )                        end of look-ahead
Related