Search and replace

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Ted.

···

--
Posted via http://www.ruby-forum.com/.

John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Ted.

try

(["one", "two", "three", "four"].zip ["crazy", "monkeys", "go", "to",
"school"]).collect {|tuple| tuple[0].gsub("o", tuple[1])}.

···

--
Posted via http://www.ruby-forum.com/\.

John Smith wrote:

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Have you got something simple working yet? For example, you could write
a loop which matches each of your test strings in turn, and replaces
with the corresponding target string.

str = "hello"

=> "hello"

str["el"] = "a"

=> "a"

str

=> "halo"

Once you've got that working, then you can try something more
sophisticated if your application demands it. One way would be to build
a Regexp (programmatically) which matches any of your test strings, and
use gsub with a block to perform the replacements. But it's a bit
trickier there to only replace the *first* occurrence of each.

···

--
Posted via http://www.ruby-forum.com/\.

Maybe something like this:

changes = [
  ['string1', 'replacement1'],
  ['string2', 'replacement2'],
  ...
]

File.open('somefile') do |f|
  f.each do |line|
    line_changed = false
    changes.each do |search, replacement|
      if line.sub!(search, replacement) then
        line_changed = true
        puts line
        break
      end
    end
    puts line unless line_changed
  end
end

-Jeremy

···

On 9/17/2010 2:02 PM, John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Ted.

search=%w[one four]
replace=%w[1 4]
to_do = search.zip(replace)
File.open("file").each do |x|
  to_do.each { |y| x.gsub!(y[0],y[1]); }
  puts x
end

···

--
Posted via http://www.ruby-forum.com/\.

Gary Watson wrote:

John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Ted.

try

(["one", "two", "three", "four"].zip ["crazy", "monkeys", "go", "to",
"school"]).collect {|tuple| tuple[0].gsub("o", tuple[1])}.

forgot to add, the output is

["crazyne", "twmonkeys", "three", "ftour"]

not sure if that's what you wanted, but maybe it'll give you some ideas.

···

--
Posted via http://www.ruby-forum.com/\.

That one almost works but it needs to do the
replacement only the first occurrence. What's
the easiest way to fix it to do that. I'm thinking of
a 'detect' but I'm not sure where I'd put it.

Jeremy Bopp wrote:

···

On 9/17/2010 2:02 PM, John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Maybe something like this:

changes = [
  ['string1', 'replacement1'],
  ['string2', 'replacement2'],
  ...
]

File.open('somefile') do |f|
  f.each do |line|
    line_changed = false
    changes.each do |search, replacement|
      if line.sub!(search, replacement) then
        line_changed = true
        puts line
        break
      end
    end
    puts line unless line_changed
  end
end

-Jeremy

--
Posted via http://www.ruby-forum.com/\.

Both solutions almost work, only that I want the first instance to be
replaced.
For example

1 4
1 4
1 5
1 4
1 5

one four
1 4
1 5
1 4
1 5

Steel Steel wrote:

···

John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Ted.

search=%w[one four]
replace=%w[1 4]
to_do = search.zip(replace)
File.open("file").each do |x|
  to_do.each { |y| x.gsub!(y[0],y[1]); }
  puts x
end

--
Posted via http://www.ruby-forum.com/\.

I'm not sure what you mean by only replacing the first occurrence. Are
you saying that there could be more than 1 line in the file which could
match a given search string but that you only want the first one of
those to be processed? Maybe you could give a trivial example of some
kind showing what you have and what you want to get.

-Jeremy

···

On 09/17/2010 07:51 PM, John Smith wrote:

Jeremy Bopp wrote:

On 9/17/2010 2:02 PM, John Smith wrote:

Hi everyone,

I want to be able to run a program that will do a bunch
of searches specified in an array of strings, and replace the
first occurrence of those strings with strings specified on a
second array for a given text file.

What would be the best way to do this?

Maybe something like this:

changes = [
  ['string1', 'replacement1'],
  ['string2', 'replacement2'],
  ...
]

File.open('somefile') do |f|
  f.each do |line|
    line_changed = false
    changes.each do |search, replacement|
      if line.sub!(search, replacement) then
        line_changed = true
        puts line
        break
      end
    end
    puts line unless line_changed
  end
end

-Jeremy

That one almost works but it needs to do the
replacement only the first occurrence. What's
the easiest way to fix it to do that. I'm thinking of
a 'detect' but I'm not sure where I'd put it.

Alright, so you only want a search/replace pair to apply to a single
line in the file to be processed. After the search/replace pair has
been applied one time, it should be dropped from the list of pairs to
try so that it cannot be used on subsequent lines. Try this:

changes = [
  ['string1', 'replacement1'],
  ['string2', 'replacement2'],
  ...
]

File.open('somefile') do |f|
  f.each do |line|
    line_changed = false
    changes.each do |change|
      if line.sub!(change[0], change[1]) then
        line_changed = true
        changes.delete(change)
        puts line
        break
      end
    end
    puts line unless line_changed
  end
end

-Jeremy

···

On 09/18/2010 11:14 AM, John Smith wrote:

Both solutions almost work, only that I want the first instance to be
replaced.
For example

1 4
1 4
1 5
1 4
1 5

one four
1 4
1 5
1 4
1 5

Hmm it works perfect for what I asked.. but I realized I will probably
need it more
granular. Instead of the first occurrence within a file, the first
ocurrence in a line.

As of now it works, for this case:

1 4
1 5
1 4
1 5

one four
1 5
1 4
1 5

However,

If we have :
1 4 1 4 1 5

it will put
one four one four one 5

and I want:
one four 1 4 1 5

From here I suppose it would be a matter of working with the line. Is
there a command to replace first occurrence of a word in a line with
another word?

Something like:

line.detect_first_occurrence_and replace("1", one).

Ted.

line_changed = true
Jeremy Bopp wrote:

···

On 09/18/2010 11:14 AM, John Smith wrote:

one four
1 4
1 5
1 4
1 5

Alright, so you only want a search/replace pair to apply to a single
line in the file to be processed. After the search/replace pair has
been applied one time, it should be dropped from the list of pairs to
try so that it cannot be used on subsequent lines. Try this:

changes = [
  ['string1', 'replacement1'],
  ['string2', 'replacement2'],
  ...
]

File.open('somefile') do |f|
  f.each do |line|
    line_changed = false
    changes.each do |change|
      if line.sub!(change[0], change[1]) then
        line_changed = true
        changes.delete(change)
        puts line
        break
      end
    end
    puts line unless line_changed
  end
end

-Jeremy

--
Posted via http://www.ruby-forum.com/\.

The example I sent should do exactly what you're saying here. Are you
certain that you did not replace the sub method with gsub? Some of the
examples sent to you by others earlier specified using gsub which will
indeed perform a repeated search/replace over the string being
processed; however, the sub method will only operate once.

-Jeremy

···

On 09/18/2010 12:42 PM, John Smith wrote:

Hmm it works perfect for what I asked.. but I realized I will probably
need it more
granular. Instead of the first occurrence within a file, the first
ocurrence in a line.

As of now it works, for this case:

1 4
1 5
1 4
1 5

one four
1 5
1 4
1 5

However,

If we have :
1 4 1 4 1 5

it will put
one four one four one 5

and I want:
one four 1 4 1 5

From here I suppose it would be a matter of working with the line. Is
there a command to replace first occurrence of a word in a line with
another word?

Something like:

line.detect_first_occurrence_and replace("1", one).