[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

gsub help

hurcan solter

8/28/2007 10:11:00 PM

Hi there;
this is more of a regexp question but I'de be happy if you help me
since i am doing it in ruby.
i want to beautify some line by inserting or removing some space
around the operators like = or ==
so i came up with an expression like;

line.gsub!(/\s*([=]+)\s*/ ,' \1 ')

But it applies every = on the line ofc, but I want to exclude
expressions between quotation marks ("sth=sth") or regexp (/sth=sth/).
I've tried negated character classes and such to no avail.How can I do
this?
Any help would be greatly appreciated...
Hurcan

6 Answers

Dan Zwell

8/28/2007 11:16:00 PM

0

hurcan solter wrote:
> Hi there;
> this is more of a regexp question but I'de be happy if you help me
> since i am doing it in ruby.
> i want to beautify some line by inserting or removing some space
> around the operators like = or ==
> so i came up with an expression like;
>
> line.gsub!(/\s*([=]+)\s*/ ,' \1 ')
>
> But it applies every = on the line ofc, but I want to exclude
> expressions between quotation marks ("sth=sth") or regexp (/sth=sth/).
> I've tried negated character classes and such to no avail.How can I do
> this?
> Any help would be greatly appreciated...
> Hurcan
>
>
>

Hurcan,
That's a very hard problem. If you think creatively, you can probably
come up with a decent algorithm, and then a handful of examples that
break it. For each "=" or "==", you need to decide whether it is between
a pair of unescaped slashes, quotes, or other form of quoting (like %Q||
or %x{}). I doubt there is any way to do this with a regexp. You need to
write some code that makes decisions about whether any of the following
symbols has semantic meaning:
|\{}@^#() and any other that can be used in the % quoting construct

Once you determine which ones have meaning (and which are escaped, or
insignificant in their current context), you can decide whether some "="
should be re-spaced, based on its position relative to these characters.
The more I think about it, the more I think you can't do this without
writing a ruby parser.

puts ("this problem is nontrivial" == true)
puts %q("this problem is nontrivial" == true)
puts %q("this problem is nontrivial", says a

string == true)

Good luck,
Dan

Logan Capaldo

8/29/2007 12:35:00 AM

0

On 8/28/07, hurcan solter <hsolter@gmail.com> wrote:
> Hi there;
> this is more of a regexp question but I'de be happy if you help me
> since i am doing it in ruby.
> i want to beautify some line by inserting or removing some space
> around the operators like = or ==
> so i came up with an expression like;
>
> line.gsub!(/\s*([=]+)\s*/ ,' \1 ')
>
> But it applies every = on the line ofc, but I want to exclude
> expressions between quotation marks ("sth=sth") or regexp (/sth=sth/).
> I've tried negated character classes and such to no avail.How can I do
> this?
This is not a job for regexps. This is a job for a ruby parser.
> Any help would be greatly appreciated...
> Hurcan
>
>
>

William James

8/29/2007 1:11:00 AM

0

On Aug 28, 5:11 pm, hurcan solter <hsol...@gmail.com> wrote:
> Hi there;
> this is more of a regexp question but I'de be happy if you help me
> since i am doing it in ruby.
> i want to beautify some line by inserting or removing some space
> around the operators like = or ==
> so i came up with an expression like;
>
> line.gsub!(/\s*([=]+)\s*/ ,' \1 ')
>
> But it applies every = on the line ofc, but I want to exclude
> expressions between quotation marks ("sth=sth") or regexp (/sth=sth/).
> I've tried negated character classes and such to no avail.How can I do
> this?
> Any help would be greatly appreciated...
> Hurcan

If " and / are the only wrappers you have to worry
about, this may work.

DATA.each{|line|
line.chomp!

array = line.scan(
%r{
\G
(?:
[^"/]+
|
"
(?> \\. | [^"] ) *
"
|
/
(?> \\. | [^/] ) *
/
)
}xm
).map{|s|
if s =~ %r{^[^"/]}
s.gsub!( /\s*(=+)\s*/, ' \1 ' )
end
s
}
puts array.join

}

__END__
/x==9/ { print "x==9 and AWK is everywhere!"; x=9 }
/\/x==9/ { print "x==\"9"; x==9 }

Peña, Botp

8/29/2007 4:47:00 AM

0

From: hurcan solter [mailto:hsolter@gmail.com]
# line.gsub!(/\s*([=]+)\s*/ ,' \1 ')
#
# But it applies every = on the line ofc, but I want to exclude
# expressions between quotation marks ("sth=sth") or regexp (/sth=sth/).

after reviewing WJames post (thanks james), i think you are not far to the solution. You just need to include the exceptions first, then gsub further to that. gsub accepts a block, so flexibility is unlimited, eg,

> str
=> "/x==9/ { print \"x==9 and AWK is everywhere!\"; x=9 }"

let's create our main regex sub and test if we can get back to the original str,

> p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| s }
"/x==9/ { print \"x==9 and AWK is everywhere!\"; x=9 }"
=> nil

ok. now let's view our captures. let's put some markers/tags.

> p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| "<<"+s+">>" }
"<</x==9/>> { print <<\"x==9>> and AWK is everywhere!\"; <<x=9>> }"
=> nil

ah, i think we're capturing right for this case of str

now let's test the inner substitution. note the gsub inside the block. the expression gets simpler since we've already filtered thru the first/main regexp.

> p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| s.gsub(/(=+)/,' \1 ') }
"/x == 9/ { print \"x == 9 and AWK is everywhere!\"; x = 9 }"
=> nil

ok.
now, let us combine that one w the first one (the noop), using an inline if (i'm assumming you want a one-liner) filtering thru the exception you want, ie, no ["\/]

> p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| s=~/["\/]/ ? s : s.gsub(/(=+)/,' \1 ') }
"/x==9/ { print \"x==9 and AWK is everywhere!\"; x = 9 }"
=> nil

is that ok?

kind regards -botp

Thibaut Barrère

8/29/2007 11:46:00 AM

0

> This is not a job for regexps. This is a job for a ruby parser.

Maybe parsing with http://www.zenspider.com/ZSS/Products/...
then regenerating the source from the parsed output could be good.

(didn't try myself - this is just a rough idea, and you would have to
ensure nothing get missed by the parser!)

Thibaut

William James

8/29/2007 5:58:00 PM

0

On Aug 28, 11:46 pm, Pe?a, Botp <b...@delmonte-phil.com> wrote:
> From: hurcan solter [mailto:hsol...@gmail.com]
> # line.gsub!(/\s*([=]+)\s*/ ,' \1 ')
> #
> # But it applies every = on the line ofc, but I want to exclude
> # expressions between quotation marks ("sth=sth") or regexp (/sth=sth/).
>
> after reviewing WJames post (thanks james), i think you are not far to the solution. You just need to include the exceptions first, then gsub further to that. gsub accepts a block, so flexibility is unlimited, eg,
>
> > str
>
> => "/x==9/ { print \"x==9 and AWK is everywhere!\"; x=9 }"
>
> let's create our main regex sub and test if we can get back to the original str,
>
> > p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| s }
>
> "/x==9/ { print \"x==9 and AWK is everywhere!\"; x=9 }"
> => nil
>
> ok. now let's view our captures. let's put some markers/tags.
>
> > p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| "<<"+s+">>" }
>
> "<</x==9/>> { print <<\"x==9>> and AWK is everywhere!\"; <<x=9>> }"
> => nil
>
> ah, i think we're capturing right for this case of str
>
> now let's test the inner substitution. note the gsub inside the block. the expression gets simpler since we've already filtered thru the first/main regexp.
>
> > p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| s.gsub(/(=+)/,' \1 ') }
>
> "/x == 9/ { print \"x == 9 and AWK is everywhere!\"; x = 9 }"
> => nil
>
> ok.
> now, let us combine that one w the first one (the noop), using an inline if (i'm assumming you want a one-liner) filtering thru the exception you want, ie, no ["\/]
>
> > p str.gsub(/\S*\s*([=]+)\s*\S*/){|s| s=~/["\/]/ ? s : s.gsub(/(=+)/,' \1 ') }
>
> "/x==9/ { print \"x==9 and AWK is everywhere!\"; x = 9 }"
> => nil


>> irb --prompt xmp
str='/x==9/ {print "so x=9 and AWK is everywhere!"; x=9 }'
==>"/x==9/ {print \"so x=9 and AWK is everywhere!\"; x=9 }"
str.gsub(/\S*\s*([=]+)\s*\S*/){|s|
s=~/["\/]/ ? s : s.gsub(/(=+)/,' \1 ') }
==>"/x==9/ {print \"so x = 9 and AWK is everywhere!\"; x = 9 }"