Felix Windt
10/8/2007 12:54:00 PM
> -----Original Message-----
> From: Jesús Gabriel y Galán [mailto:jgabrielygalan@gmail.com]
> Sent: Monday, October 08, 2007 5:25 AM
> To: ruby-talk ML
> Subject: Re: regexp question - look for parentheses then remove them
>
> On 10/8/07, Max Williams <toastkid.williams@gmail.com> wrote:
> > I'm struggling with a regular expression problem, can anyone help?
> >
> > I want to take a string, look for anything in parentheses,
> and if i find
> > anything, put it into an array, minus the parentheses.
> >
> > currently i'm doing this:
> >
> > parentheses = /\(.*\)/
> > array = string.scan(parentheses)
> >
> > This gives me eg
> >
> > "3 * (1 + 2)" => ["(1 + 2)"]
> >
> > - but is there an easy way to strip the parentheses off
> before putting
> > it into the array?
> >
> > eg
> > "3 * (1 + 2)" => ["1 + 2"]
> >
> > In addition, if i have nested parentheses inside the outer
> parentheses,
> > i want to keep them, eg
> >
> > "3 * (1 + (4 / 2))" => ["1 + (4 / 2)"]
> >
> > can anyone show me how to do this?
>
> x = "3 * (1 + 2)".match(/\((.*)\)/)
> x.captures
> => ["1 + 2"]
> x = "3 * (2 + (1 + 3))".match(/\((.*)\)/)
> x.captures
> => ["2 + (1 + 3)"]
>
> Hope this helps,
>
> Jesus.
>
That can fail if you have more than one bracket pair on the lowest level:
irb(main):002:0> "3 * (2 + (1 + 3)) + (1 * 4)".match(/\((.*)\)/).to_a
=> ["(2 + (1 + 3)) + (1 * 4)", "2 + (1 + 3)) + (1 * 4"]
I'm not sure you can match more complex examples using a regular expression
- you may be able to pull something off with lookaheads, but I think it'd be
easier to just parse the string manually and count opened brackets:
$ cat para.rb
def para(str)
open = 0
matches = []
current = ""
str.split(/\s*/).each do |char|
if char == ")"
open -= 1
if open == 0
matches << current
current = ""
else
current << char
end
elsif char == "("
open += 1
if open > 1
current << char
end
elsif open > 0
current << char
end
end
matches
end
$ irb
irb(main):001:0> require 'para'
=> true
irb(main):002:0> para("1+2")
=> []
irb(main):003:0> para("(1+2)")
=> ["1+2"]
irb(main):004:0> para("(1+2)*3")
=> ["1+2"]
irb(main):005:0> para("((1+2)*3)")
=> ["(1+2)*3"]
irb(main):006:0> para("((1+2)*3)+(5*6)")
=> ["(1+2)*3", "5*6"]
irb(main):007:0> para("((1+2)*3)+(5*6*(1-3*(1-4)))")
=> ["(1+2)*3", "5*6*(1-3*(1-4))"]
irb(main):008:0>
There are probably far more elegant ways.
HTH,
Felix