split-related functionalities
I use ruby 1.9.2.
gsub
/scan
iterate over matches to a given regex/string, and is used in three ways:
- If
scan
is used without a block, it returns an array of matches. - If
scan
is used with a block, it iterates over matches and performs something. - If
gsub
is used, it replaces the matches with what is given as the second argument or as the block, and returns a string.
On the other hand, there is split
that matches the complement of what gsub
/scan
match. However, there is only one way to use this:
- If
split
is used without a block, It returns an array of the complement of the matches.
I wanted the other two missing usages related to split
, and tried to implement them. The following every_other
extends split
so that it can be used like scan
.
class String
def every_other arg, &pr
pr ? split(arg).to_enum.each{|e| pr.call(e)} : split(arg)
end
end
# usage:
'cat, two dogs, horse,开发者_开发技巧 three cows'.every_other(/,\s*/) #=> array
'cat, two dogs, horse, three cows'.every_other(/,\s*/){|s| p s} # => executes the block
Then, I tried to implement the counterpart of gsub
, but cannot do it well.
class String
def gsub_other arg, rep = nil, &pr
gsub(/.*?(?=#{arg}|\z)/, *rep, &pr)
end
end
# usage
'cat, two dogs, horse, three cows'.gsub_other(/,\s*/, '[\1]') # or
'cat, two dogs, horse, three cows'.gsub_other(/,\s*/) {|s| "[#{s}]"}
# Expected => "[cat], [two dogs], [horse], [three cows]"
# Actual output => "[cat][],[ two dogs][],[ horse][],[ three cows][]"
- What am I doing wrong?
- Is this approach correct? Is there a better way to do it, or are there already methods that do this?
- Do you have suggestions about the method names?
It's not beautiful but this seems to works
s='cat, two dogs, horse, three cows'
deli=",\s"
s.gsub(/(.*?)(#{deli})/, '[\1]\2').gsub(/(.*\]#{deli})(.*)/, '\1[\2]')
=> "[cat], [two dogs], [horse], [three cows]"
The following feels a little better
s.split(/(#{deli})/).map{|s| s!=deli ? "[#{s}]" : deli}.join
精彩评论