# Regexp for parsing?

**URL:** <https://www.ruby-forum.com/t/regexp-for-parsing/120599>\
**Category:** Ruby\
**Created:** [November 19, 2007, 2:55am UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599 "2007-11-19T02:55:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [November 19, 2007, 2:55am UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/1 "2007-11-19T02:55:37Z")

</div>

I understand regular expressions, but can someone please explain this:

re = %r/((?((?:\[()]|[^()]|\g)\*)))/

By the way, this only works with the Oniguruma engine (Ruby 1.9).

So, now that there is the capability to match balanced parens and so  
forth, does this mean that the new regular expression engine can be  
used to construct simple parsers (matching language constructs)?

---

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [November 19, 2007, 2:25pm UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/2 "2007-11-19T14:25:58Z")

</div>

On Nov 18, 8:50 pm, Wayne M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I understand regular expressions, but can someone please explain this:
> 
> re = %r/((?((?:\[()]|[^()]|\g)\*)))/
> 
> By the way, this only works with the Oniguruma engine (Ruby 1.9).
> 
> So, now that there is the capability to match balanced parens and so  
> forth, does this mean that the new regular expression engine can be  
> used to construct simple parsers (matching language constructs)?

%r/ … /  
– regexp delimter (why they didn’t just use / … /, I don’t know)  
( … )  
– non-capturing group - (normally would be capturing, but see  
[サービス終了のお知らせ](http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt), part 10, case 3)  
– seems rather useless, given that the only contained item is a  
capturing group  
(? … )  
– capturing named group (see  
[サービス終了のお知らせ](http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt),  
part 7)  
( … )  
– literal parentheses surrounding pattern  
(?: … | … | … )\*  
– non-capturing group of 3 alternatives, repeated 0 or more times  
\[()]  
– escaped literal parens  
[^()]  
– anything except parens  
\g  
– match the pg-named pattern here (recursive sub-exp - see  
[サービス終了のお知らせ](http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt), part 9)

---

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [November 20, 2007, 11:42pm UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/3 "2007-11-20T23:42:58Z")

</div>

Thanks, I understand nearly everything now. It really shows the power  
of the oniguruma engine for regular expressions. By the way, the comma  
caused a Japanese site to come up. For people’s reference the manual  
for onigurama is at:

[http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt](http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt)

That’s a great reference, but I still didn’t understand this:

Noah E. wrote:

> \[()]  
> – escaped literal parens

What is that pattern? I’ve never seen that before. What does it match?  
Where can I read about that?

Why would that be there since a new open paren should start another  
instance of , shouldn’t it?

So, obviously, I’m still a little confused.

---

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [November 21, 2007, 1:59am UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/4 "2007-11-21T01:59:40Z")

</div>

On Nov 20, 2007, at 14:42 , Wayne M. wrote:

> Noah E. wrote:
> 
> > \[()]  
> > – escaped literal parens
> 
> What is that pattern? I’ve never seen that before. What does it  
> match?  
> Where can I read about that?

“(” or “)”

---

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [November 21, 2007, 3:11pm UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/5 "2007-11-21T15:11:13Z")

</div>

Noah E. wrote:

> On Nov 18, 8:50 pm, Wayne M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > I understand regular expressions, but can someone please explain this:
> > 
> > re = %r/((?((?:\[()]|[^()]|\g)_)))/  
> > snip  
> > (?: … | … | … )_  
> > – non-capturing group of 3 alternatives, repeated 0 or more times  
> > \[()]  
> > – escaped literal parens  
> > [^()]  
> > – anything except parens  
> > \g  
> > – match the pg-named pattern here

Ok, so there are 3 alternatives in the non-capturing group:

1. An open or close parenthesis
2. Any character except a paren
3. A pattern that starts with an open paren

Am I the only one that finds this strange?

---

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [November 21, 2007, 1:58am UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/6 "2007-11-21T01:58:29Z")

</div>

On Nov 18, 2007, at 17:55 , Wayne M. wrote:

> I understand regular expressions, but can someone please explain this:
> 
> re = %r/((?((?:\[()]|[^()]|\g)\*)))/
> 
> By the way, this only works with the Oniguruma engine (Ruby 1.9).
> 
> So, now that there is the capability to match balanced parens and so  
> forth, does this mean that the new regular expression engine can be  
> used to construct simple parsers (matching language constructs)?

No, translated to 1.8, the regex would be:

%r/((((?:\[()]|[^()]|\2)\*)))/

---

<div class="post-metadata">

**Author:** ![wemagor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/8edcca/32.png) [@wemagor](https://www.ruby-forum.com/u/wemagor)\
**Post date:** [December 3, 2007, 8:07pm UTC](https://www.ruby-forum.com/t/regexp-for-parsing/120599/7 "2007-12-03T20:07:08Z")

</div>

On Nov 21, 9:11 am, Wayne M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > [^()]  
> > – anything except parens  
> > \g  
> > – match the pg-named pattern here
> 
> Ok, so there are 3 alternatives in the non-capturing group:
> 
> 1. An open or close parenthesis  
> correction. As Eric said above, an escaped (read, with leading  
> backslash) parenthesis.

> 1. Any character except a paren  
> yup.
> 2. A pattern that starts with an open paren  
> AND ends in a close paren, and contains only, non-parens, escaped  
> parens, and balanced pairs of parens.
> 
> Am I the only one that finds this strange?  
> Doubtful :). You may be one of the ones to which this is new, though.

I find it strange that only recognize parenthesis escapes, and not  
escaped backslashes. So you can do something like:  
( ( )  
and match correctly, but there’s no way to do a balanced pair of  
parentheses containing just a backslash:  
() – no  
(\) – no  
(\) – no  
(\ ) – matches, but has an extra space.

I would have replaced ‘\[()]’ by ‘\[()\]’ so that ‘(\)’ would  
match.
