Regexp replace every other one

When i have a string like:

puts “Mike Lan move the string abc def”.gsub(/(\A|\s)(.{3})($|\s)/,"
new_value ")

it only replaces two same as the next one only replaces every other one
what a im missing??

puts “gta gtb gtc gxd gte”.gsub(/(\A|\s)(.{3})($|\s)/," new_value ")

thank you

On Sat, Mar 31, 2012 at 10:17 PM, gabe gabriellini
[email protected] wrote:

puts “Mike Lan move the string abc def”.gsub(/(\A|\s)(.{3})($|\s)/,"
new_value ")

it only replaces two same as the next one only replaces every other one
what a im missing??

The ending pattern ($|\s) is consuming what would be matched by the
leading pattern (\A|\s) every other match. Making the first part
optional will work:

/(\A|\s)?(.{3})($|\s)/

If you know the pattern of what you trying to match between the
spaces, for example alphabet only, use a more explicit pattern instead
of .{3}. That way you wouldn’t have to deal with the spaces, only what
you want to replace.

“abc def ghi jkl mno”.gsub(/[a-z]{3}/, “123”)
=> “123 123 123 123 123”

Regards,
Ammar

thank you Ammar

this works great:

puts “abc def ghi jkl mno”.gsub(/[a-z]{3}/, “123”)

The only problem i have is when i use a string like this one:

puts “gabriel y martha iba gtz ibanez nat”.gsub(/(\A|\s)([a-zA-Z]{3})
($|\s)/," Gutierrez ")

the gtz after the iba does not get replaced

I understand what you explain but I don’t think I am going to check a
hole database with more than 5 thousand records.

the easiest way would be to run the code twice but where is DRY.

Thanks everyone don’t take wrong i will keep digging.
gabriel

On Sat, Mar 31, 2012 at 11:37 PM, gabe gabriellini
[email protected] wrote:

I understand what you explain but I don’t think I am going to check a
hole database with more than 5 thousand records.

I don’t think so. I in no way meant for you to change the data. I
wanted to expose the problem in the regular expression better, not the
data.

the easiest way would be to run the code twice but where is DRY.

The easiest way would be to understand what doesn’t work in that
expression and find a better way to accomplish your goal.

http://ruby.runpaint.org/regexps

Regards,
Ammar

gabe gabriellini wrote in post #1054415:

this works great:

puts “abc def ghi jkl mno”.gsub(/[a-z]{3}/, “123”)

The only problem i have is when i use a string like this one:

puts “gabriel y martha iba gtz ibanez nat”.gsub(/(\A|\s)([a-zA-Z]{3})
($|\s)/," Gutierrez ")

the gtz after the iba does not get replaced

I think you want \b (word boundary) to create something like this:

irb(main):001:0> “gabriel y martha iba gtz ibanez nat”.gsub /\b\w{3}\b/,
‘X’
=> “gabriel y martha X X ibanez X”

Kind regards

robert

On Sat, Mar 31, 2012 at 11:09 PM, gabe gabriellini
[email protected] wrote:

thank you Ammar

You’re welcome!

The only problem i have is when i use a string like this one:

puts “gabriel y martha iba gtz ibanez nat”.gsub(/(\A|\s)([a-zA-Z]{3})
($|\s)/," Gutierrez ")

the gtz after the iba does not get replaced

This is the same problem i mentioned. The pattern matches:

  • the beginning of line (\A) or a space (\s)
  • followed by 3 alphabet characters ([a-zA-Z]{3})
  • followed by end of line ($) or a space (\s)

When this matches iba, it matchs " iba " (that is space iba space).
When it gets to the gtz part, it doesn’t match because it needs to
match a beginning of a line (\A) or a space (\s) again, but these
space before it has already been matched. So it fails.

To help in understanding this, add an extra space between the ibz and
gtz. Then it will work.

Good luck,
Ammar

Thank you so much Robert K. I knew it was possible that works great.
I actually did it with:

myfield = %w[gabriel y martha iba gtz ibanez nat]
myfield.each { |word| if word.length==3 ;word.gsub!(word,“gutierrez”)
end }
puts myfield.join " "

but I was not happy

gabe