Regexp, matching only the content within parentheses

E

Emil Kampp

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
 
G

Gunther Diemant

[Note: parts of this message were removed to make it a legal post.]

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

For your example string:

"d_(1)+d_(23)".scan(/\(([^)]+)\)/)
#=> [["1"],["23"]]
 
E

Emil Kampp

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
 
7

7stud --

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.
 
E

Emil Kampp

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
 
7

7stud --

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

Robert Klemme

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{(?<ne> \( (?:\g<ne>|[^()]+)* \) )}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{(?<ne> \( (?: \g<ne> | [^()] )* \) )}x
=> [["(a)"], ["(x)"], ["(2)"], ["(5x//f'(x))"]]

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

Kind regards

robert
 
R

Robert Klemme

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{(?<ne> \( (?:\g<ne>|[^()]+)* \) )}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{(?<ne> \( (?: \g<ne> | [^()] )* \) )}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{\( (?<ne> [^()] | \( \g<ne> \) )* // \g<ne>* \)}x.match s
=> #<MatchData "(5x//f'(x))" ne:"(x)">

:)

Cheers

robert
 
R

Robert Klemme

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{(?<ne> \( (?:\g<ne>|[^()]+)* \) )}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{(?<ne> \( (?: \g<ne> | [^()] )* \) )}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{\( (?<ne> [^()] | \( \g<ne> \) )* // \g<ne>* \)}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{\( (?<all> (?<ne> [^()] | \( \g<ne> \) )* //
\g<ne>* ) \)}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
 
E

Emil Kampp

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
 
7

7stud --

Robert K. wrote in post #989148:
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{(?<ne> \( (?:\g<ne>|[^()]+)* \) )}x

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

Robert Klemme

Robert K. wrote in post #989148:
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{(?<ne> \( (?:\g<ne>|[^()]+)* \) )}x

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,017
Latest member
GreenAcreCBDGummiesReview

Latest Threads

Top