URLs are complex and you'll save yourself a lot of work, and potential trouble, by using a library designed for manipulating them instead of trying to roll your own with regular expressions. Fortunately, Ruby comes with a few, among them URI. Using it is easy:
require "uri"
str = "/ei/sort.do?layoutCollection=0&layoutCollectionProperty=&layoutCollectionState=0&pagerPage=1"
# Create a URI object to easily get the query portion of the string
uri = URI(str)
# Decode the query values into a Hash
query = URI.decode_www_form(uri.query).to_h
# Or, if you're using Ruby 2.0 or earlier:
# query = Hash[URI.decode_www_form(uri.query)]
puts query
# => { "layoutCollection" => "0",
# "layoutCollectionProperty" => "",
# "layoutCollectionState" => "0",
# "pagerPage" => "1"
# }
# Change any values we want to change
query["layoutCollectionState"] = "SOME_OTHER_VALUE"
# Re-encode the query values and assign them back to the URI object
uri.query = URI.encode_www_form(query)
# Turn it back into a string
puts uri.to_s
# => /ei/sort.do?layoutCollection=0&layoutCollectionProperty=&
# ... layoutCollectionState=SOME_OTHER_VALUE&pagerPage=1
And for what it's worth it needn't be that verbose:
def merge_query_values(url, hsh)
URI(url).tap do |uri|
uri.query = URI.encode_www_form(
URI.decode_www_form(uri.query).to_h.merge!(hsh) )
end.to_s
end
str = "/ei/sort.do?layoutCollection=0&layoutCollectionProperty=&layoutCollectionState=0&pagerPage=1"
puts merge_query_values(str, "layoutCollectionState" => "SOME_OTHER_VALUE",
"foo" => "BAR")
# => /ei/sort.do?layoutCollection=0&layoutCollectionProperty=&
# ... layoutCollectionState=SOME_OTHER_VALUE&pagerPage=1&foo=BAR
layoutCollectionState=2324you want to replace2324by something else correct?