# Gsub help

**URL:** <https://www.ruby-forum.com/t/gsub-help/113226>\
**Category:** Ruby\
**Created:** [August 29, 2007, 12:15am UTC](https://www.ruby-forum.com/t/gsub-help/113226 "2007-08-29T00:15:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 12:15am UTC](https://www.ruby-forum.com/t/gsub-help/113226/1 "2007-08-29T00:15:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 1:17am UTC](https://www.ruby-forum.com/t/gsub-help/113226/2 "2007-08-29T01:17:03Z")

</div>

hurcan solter wrote:

> 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

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 2:36am UTC](https://www.ruby-forum.com/t/gsub-help/113226/3 "2007-08-29T02:36:08Z")

</div>

On 8/28/07, hurcan solter [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

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

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 3:16am UTC](https://www.ruby-forum.com/t/gsub-help/113226/4 "2007-08-29T03:16:10Z")

</div>

On Aug 28, 5:11 pm, hurcan solter [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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 }

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 1:51pm UTC](https://www.ruby-forum.com/t/gsub-help/113226/5 "2007-08-29T13:51:14Z")

</div>

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

Maybe parsing with [zenspider projects | software projects | by ryan davis](http://www.zenspider.com/ZSS/Products/ParseTree/)  
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

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 6:47am UTC](https://www.ruby-forum.com/t/gsub-help/113226/6 "2007-08-29T06:47:21Z")

</div>

From: hurcan solter [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# 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

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [August 29, 2007, 8:01pm UTC](https://www.ruby-forum.com/t/gsub-help/113226/7 "2007-08-29T20:01:31Z")

</div>

On Aug 28, 11:46 pm, Peña, Botp [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> =\> “/x==9/ { print "x==9 and AWK is everywhere!"; x=9 }”
> 
> > p str.gsub(/\S\*\s\*([=]+)\s\*\S\*/){|s| “\<\<”+s+“\>\>” }  
> > “/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 }"
