4

I need to replace some text in a db field based on a regex search on a string.

So far, I have this:

foo = my_string.gsub(/\[0-9\]/, "replacement" + array[#] + "text")

So, I'm searching in the field for each instance of a number surrounded by brackets ([1],[2],etc.). What I would like to do is find each number (within the brackets) in the search, and have that number used to find the specific array node.

Any ideas? Let me know if anyone needs any kind of clarification.

1 Answer 1

10

The easiest would be to use the block form of gsub:

foo = my_string.gsub(/\[(\d+)\]/) { array[$1.to_i] }

And note the capture group inside the regex. Inside the block, the global $1 is what the first capture group matched.

You could also use a named capture group but that would require a different global because $~ is (AFAIK) the only way to get at the current MatchData object inside the block:

foo = my_string.gsub(/\[(?<num>\d+)\]/) { |m| a[$~[:num].to_i] }

For example:

>> s = 'Where [0] is [1] pancakes [2] house?'
=> "Where [0] is [1] pancakes [2] house?"
>> a = %w{a b c}
=> ["a", "b", "c"]

>> s.gsub(/\[(\d+)\]/) { a[$1.to_i] }
=> "Where a is b pancakes c house?"

>> s.gsub(/\[(?<num>\d+)\]/) { |m| a[$~[:num].to_i] }
=> "Where a is b pancakes c house?"
Sign up to request clarification or add additional context in comments.

2 Comments

The named capture example doesn't work. m is a string and m['num'] doesn't return the named capture. You could use s.gsub(/\[(?<num>\d+)\]/) { a[$~[:num].to_i] }
@Stefan: Wow, how did I miss that. The gsub(/\[(\d+)\]/) { |m| a[m[1].to_i] } version doesn't really work either (unless the numbers are guaranteed to be only one digit).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.