Regexp, matching only the content within parentheses

Hi.

I’m hoping that someone can give me some pointers. I need to match the
content within the parentheses only, from the following string (this is
an example string, but the structure is consistent):

d_(1)+d_(23)

So far I have matched something else using \b to match a closing tic
(`), but that doesn’t seem to work here:

_((.+)\b[^)]

Best regards
// Emil

I think /(([^)]+))/ should work.

For your example string:

“d_(1)+d_(23)”.scan(/(([^)]+))/)
#=> [[“1”],[“23”]]


gunther

2011/3/24 Emil K. [email protected]

Thank you, that pointed me in the right direction. But now I’m facing
another problem (still kinda the same). I have this string:

f_(a)(x)=x^(2)+(5x//f’(x))

Where i need to capture everything within the parentheses surrounding
the double-slashes (//), like so:

(5x//f’(x))

My problem is that I can’t seem to get past the last parentheses around
the f’(x). This is what I’ve gotten so far:

(([^(])//[^)])

And that will match 5x//f'(x, so I need to get past that last closing
parentheses around the x.

I hope that someone (Gunther, if you’r still up for it?) can help me.

Best regards
// Emil

Regexes are “greedy” by default. Don’t look for [^)] characters,
instead look for a closing parentheses:

str = “aaa( abc(def)ghi (jkl)(mno) )”

if (str =~ /[(] .* [)]/xms )
puts Regexp.last_match[0]
end

–output:–
( abc(def)ghi (jkl)(mno) )

How you will know when to use non-greedy patterns, like [^)] or .*?,
versus the natural greediness of a regex is not clear to me.

perl’s regexes have a recursive feature, which can solve your problem.
Want to call an external script? In fact, perl has a library which
contains regexes for hard to solve problems, so you don’t even have to
write the regex yourself. Here’s what it looks like:

$regex = qr{
(
(?:
(?> [^()]++ ) # Non-parens without
backtracking
|
(??{ $regex }) # Group with matching
parens
)*
)
}x;

I have upgraded the regular expression somewhat, to enclose other
similar situations, but I still have the problem of not getting the last
parenthesis (the one completely ending the statement) included in the
expression (while not grabbing anything beyond the parentheses).

This is the upgraded expression:

((()([^(])//([^)])()))

// Emil

On Fri, Mar 25, 2011 at 2:58 AM, 7stud – [email protected]
wrote:

perl’s regexes have a recursive feature, which can solve your problem.
Want to call an external script?

Not necessary: Ruby has it, too.

irb(main):001:0> s=“x(a(b)()c)y”
=> “x(a(b)()c)y”
irb(main):002:0> %r{(? ( (?:\g|[^()]+)* ) )}x.match s
=> #<MatchData “(a(b)()c)” ne:"(a(b)()c)">

irb(main):003:0> s = “f_(a)(x)=x^(2)+(5x//f’(x))”
=> “f_(a)(x)=x^(2)+(5x//f’(x))”
irb(main):004:0> s.scan %r{(? ( (?: \g | [^()] )* ) )}x
=> [["(a)"], ["(x)"], ["(2)"], ["(5x//f’(x))"]]

See http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt

Kind regards

robert

On Fri, Mar 25, 2011 at 9:28 AM, Robert K.
[email protected] wrote:

irb(main):002:0> %r{(? ( (?:\g|[^()]+)* ) )}x.match s

irb(main):054:0> %r{( (? [^()] | ( \g ) )* // \g* )}x.match s
=> #<MatchData “(5x//f’(x))” ne:"(x)">

… and if you want to extract the content of the outer bracket
automatically you can do

irb(main):007:0> md = %r{( (? (? [^()] | ( \g ) )* //
\g* ) )}x.match s
=> #<MatchData “(5x//f’(x))” all:“5x//f’(x)” ne:"(x)">
irb(main):008:0> md[:all]
=> “5x//f’(x)”

Kind regards

robert

On Fri, Mar 25, 2011 at 9:14 AM, Robert K.
[email protected] wrote:

irb(main):003:0> s = “f_(a)(x)=x^(2)+(5x//f’(x))”
=> “f_(a)(x)=x^(2)+(5x//f’(x))”
irb(main):004:0> s.scan %r{(? ( (?: \g | [^()] )* ) )}x
=> [["(a)"], ["(x)"], ["(2)"], ["(5x//f’(x))"]]

See http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt

PS: Here’s a more targeted one

irb(main):054:0> %r{( (? [^()] | ( \g ) )* // \g*
)}x.match s
=> #<MatchData “(5x//f’(x))” ne:"(x)">

:slight_smile:

Cheers

robert

Thank you people. I will try and work with this stuff. It has given an
entry point into where to start, so that’s fantastic.

// Emil

Robert K. wrote in post #989148:

On Fri, Mar 25, 2011 at 2:58 AM, 7stud – [email protected]
wrote:

perl’s regexes have a recursive feature, which can solve your problem.
Want to call an external script?

Not necessary: Ruby has it, too.

irb(main):002:0> %r{(? ( (?:\g|[^()]+)* ) )}x

How come the perl regex uses the non-backtracking ++, and yours doesn’t
appear to do the equivalent? Hmmm… I think the (?> also means
non-backtracking.

On 26.03.2011 04:08, 7stud – wrote:

How come the perl regex uses the non-backtracking ++, and yours doesn’t
appear to do the equivalent?

the perl regexp”? What do you mean exactly?

Kind regards

robert

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs