Reputation: 5462
I have a string which contains a 2-D array.
b= "[[1, 2, 3], [4, 5, 6]]"
c = b.gsub(/(\[\[)/,"[").gsub(/(\]\])/,"]")
The above is how I decide to flatten it to:
"[1, 2, 3], [4, 5, 6]"
Is there a way to replace the leftmost and rightmost brackets without doing a double gsub
call? I'm doing a deeper dive into regular expressions and would like to see different alternatives.
Sometimes, the string may be in the correct format as comma delimited 1-D arrays.
Upvotes: 0
Views: 962
Reputation: 23307
The gsub
method accepts a hash, and anything that matches your regular expression will be replaced using the keys/values in that hash, like so:
b = "[[1, 2, 3], [4, 5, 6]]"
c = b.gsub(/\[\[|\]\]/, '[[' => '[', ']]' => ']')
That may look a little jumbled, and in practice I'd probably define the list of swaps on a different line. But this does what you were looking for with one gsub, in a more intuitive way.
Another option is to take advantage of the fact that gsub
also accepts a block:
c = b.gsub(/\[\[|\]\]/){|matched_value| matched_value.first}
Here we match any double opening/closing square brackets, and just take the first letter of any matches. We can clean up the regex:
c = b.gsub(/\[{2}|\]{2}/){|matched_value| matched_value.first}
This is a more succinct way to specify that we want to match exactly two opening brackets, or exactly two closing brackets. We can also refine the block:
c = b.gsub(/\[{2}|\]{2}/, &:first)
Here we're using some Ruby shorthand. If you only need to call a simple method on the object passed into a block, you can use the &:
notation to do this. I think I've gotten it about as short and sweet as I can. Happy coding!
Upvotes: 2
Reputation: 2381
To "squeeze" consecutive occurrences of a specific character set, you can use tr_s
:
"[[1,2],[3,4]]".tr_s('[]','[]')
=> "[1,2],[3,4]"
You're saying "translate all runs of square bracket characters to one of that character". To do the same thing with regular expressions and gsub
, you can do:
"[[1,2],[3,4]]".gsub(/(\[|\])+/,'\1')
Upvotes: 1
Reputation: 160553
Don't even bother with a regular expression, just do a simple string slice:
b= "[[1, 2, 3], [4, 5, 6]]"
b[1 .. -2] # => "[1, 2, 3], [4, 5, 6]"
the string may be in the correct format as comma delimited 1D arrays
Then sense whether it is and conditionally modify it:
b= "[[1, 2, 3], [4, 5, 6]]"
b = b[1 .. -2] if b[0, 2] == '[[' # => "[1, 2, 3], [4, 5, 6]"
Regular expressions aren't universal hammers, and not everything is a nail to be hit with one.
Upvotes: 1
Reputation: 67968
\[(?=\[)|(?<=\])\]
You can try this.Replace with ``.See demo.
http://regex101.com/r/hQ1rP0/25
Upvotes: 2