Sajad Rastegar
Sajad Rastegar

Reputation: 3154

Non capturing named groups in ruby

I wrote the following regexp to match all the outer most blocks in a set of nested blocks using scan method.

input.scan(/[^{}]++\{((?:[^{}]+|\{\g<1>\})++)\}/)

or

input.scan(/[^{}]++\{(?<paren>(?:[^{}]+|\{\g<paren>\})++)\}/)

The problem with this code is that the parentheses I used for ?<paren> group are causing the scan to capture only the content of ?<paren> group while I need to capture the entire string matched by scan method. What do i need to do about this problem?

Upvotes: 1

Views: 598

Answers (1)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

When capture groups are present, the scan method will only return the content of these capture groups but will no more return the whole match.

A solution consists to put the entire pattern in a capture group to solve the problem. However, each results will be a couple of string with the content of the capture groups 1 and 2.

To avoid the problem you can rewrite the pattern with only one capture group like this:

((?<={)(?:[^{}]+|{\g<1>})*+|[^{}\s][^{}]*{\g<1>})

online demo

edit: or without capture groups at all:

(?<={)(?:[^{}]+|{\g<0>})*+|[^{}\s][^{}]*{\g<0>}

Notes: The lookbehind at the begining is here to check if you are in a recursion or not.

[^{}\s][^{}]* is used instead of [^{}]+ to avoid leading spaces and newlines.

Upvotes: 3

Related Questions