Skip to main content
new version of code
Source Link
ujifgc
  • 215
  • 3
  • 7

I have a method to replace URL parameters in an URL. It receives url as mandatory parameter and prefix and/or hash as optional parameters. Examples:

url_replace( '/news?b=2', { b: nil } )                     # => '/news'
url_replace( '/news?b=2', { b: 3 } )                       # => '/news?b=3'
url_replace( '/news?a=b', '/bar' )                         # => '/bar?a=b'
url_replace( '/news?a=b&c=d', '/bar', c: nil )             # => '/bar?a=b'

The method:

def url_replace( target, *args )
  uri = URI.parse(URI.escape target)
  if hash = args.last.kind_of?(Hash) && args.last
    query = uri.query ? CGI.parse(uri.query) : {}
    hash.each do |k,v|
      v ? query[k.to_s] = v.to_s : query.delete(k.to_s)
    end
    uri.query = query.any? ? query.map{|k,v| "#{CGI.escape k.to_s}=#{CGI.escape Array(v).join}"}.join('&') : nil
  end
  prefix = args.first.kind_of?(String) && args.first
  uri.path = CGI.escape(prefix)  if prefix
  CGI.unescape(uri.to_s)
end

I would like some refactoring or speed optimizations.

Okay, here's the code I ended up with:

def url_replace( target, *args )
  uri = URI.parse(URI::DEFAULT_PARSER.escape target)
  uri.path = CGI.escape(args.first)  if args.first.kind_of?(String)
  if args.last.kind_of?(Hash)
    query = uri.query ? CGI.parse(uri.query) : {}
    args.last.each{ |k,v| v ? query[k.to_s] = v.to_s : query.delete(k.to_s) }
    uri.query = query.any? ? URI.encode_www_form(query) : nil
  end
  CGI.unescape(uri.to_s)
end

I have a method to replace URL parameters in an URL. It receives url as mandatory parameter and prefix and/or hash as optional parameters. Examples:

url_replace( '/news?b=2', { b: nil } )                     # => '/news'
url_replace( '/news?b=2', { b: 3 } )                       # => '/news?b=3'
url_replace( '/news?a=b', '/bar' )                         # => '/bar?a=b'
url_replace( '/news?a=b&c=d', '/bar', c: nil )             # => '/bar?a=b'

The method:

def url_replace( target, *args )
  uri = URI.parse(URI.escape target)
  if hash = args.last.kind_of?(Hash) && args.last
    query = uri.query ? CGI.parse(uri.query) : {}
    hash.each do |k,v|
      v ? query[k.to_s] = v.to_s : query.delete(k.to_s)
    end
    uri.query = query.any? ? query.map{|k,v| "#{CGI.escape k.to_s}=#{CGI.escape Array(v).join}"}.join('&') : nil
  end
  prefix = args.first.kind_of?(String) && args.first
  uri.path = CGI.escape(prefix)  if prefix
  CGI.unescape(uri.to_s)
end

I would like some refactoring or speed optimizations.

I have a method to replace URL parameters in an URL. It receives url as mandatory parameter and prefix and/or hash as optional parameters. Examples:

url_replace( '/news?b=2', { b: nil } )                     # => '/news'
url_replace( '/news?b=2', { b: 3 } )                       # => '/news?b=3'
url_replace( '/news?a=b', '/bar' )                         # => '/bar?a=b'
url_replace( '/news?a=b&c=d', '/bar', c: nil )             # => '/bar?a=b'

The method:

def url_replace( target, *args )
  uri = URI.parse(URI.escape target)
  if hash = args.last.kind_of?(Hash) && args.last
    query = uri.query ? CGI.parse(uri.query) : {}
    hash.each do |k,v|
      v ? query[k.to_s] = v.to_s : query.delete(k.to_s)
    end
    uri.query = query.any? ? query.map{|k,v| "#{CGI.escape k.to_s}=#{CGI.escape Array(v).join}"}.join('&') : nil
  end
  prefix = args.first.kind_of?(String) && args.first
  uri.path = CGI.escape(prefix)  if prefix
  CGI.unescape(uri.to_s)
end

I would like some refactoring or speed optimizations.

Okay, here's the code I ended up with:

def url_replace( target, *args )
  uri = URI.parse(URI::DEFAULT_PARSER.escape target)
  uri.path = CGI.escape(args.first)  if args.first.kind_of?(String)
  if args.last.kind_of?(Hash)
    query = uri.query ? CGI.parse(uri.query) : {}
    args.last.each{ |k,v| v ? query[k.to_s] = v.to_s : query.delete(k.to_s) }
    uri.query = query.any? ? URI.encode_www_form(query) : nil
  end
  CGI.unescape(uri.to_s)
end
remove old code
Source Link
ujifgc
  • 215
  • 3
  • 7

I have a method to replace URL parameters in an URL. I can't use URI or Rack::URI because of their strict nature and tendency to raise errors on every non-standard URL. I'd like to replace the parameters if possible, or just leave them be if not.

The methodIt receives url as mandatory parameter and prefix and/or hash as optional parameters. Examples:

The method:

def url_replace( target, *args )
  hash = args.last.kind_of?(Hash) && args.last
  prefix = args.first.kind_of?(String) && args.first
  if hash
    path, _, query = target.partition ??
    hash.each do |k,v|
      k_reg = CGI.escape k.to_s
      query = query.gsub /[&^]?#{k_reg}(?:=([^&]*))?[&$]?/, ''
      query += "&#{k}=#{v}"  if v
    end
    query.gsub! /^&/, ''
    q_mark = query.present? ? ?? : ''
    target = [path, q_mark, query].join
  end
  if prefix
    return prefix  unless target.index ??
    target = target.gsub(/[^?]*(\?.*)/, prefix + '\1')
  end
  target
end

I would like some refactoring or speed optimizations.

Edit using URI and CGI:

I would like some refactoring or speed optimizations.

I have a method to replace URL parameters in an URL. I can't use URI or Rack::URI because of their strict nature and tendency to raise errors on every non-standard URL. I'd like to replace the parameters if possible, or just leave them be if not.

The method receives url as mandatory parameter and prefix and/or hash as optional parameters. Examples:

The method:

def url_replace( target, *args )
  hash = args.last.kind_of?(Hash) && args.last
  prefix = args.first.kind_of?(String) && args.first
  if hash
    path, _, query = target.partition ??
    hash.each do |k,v|
      k_reg = CGI.escape k.to_s
      query = query.gsub /[&^]?#{k_reg}(?:=([^&]*))?[&$]?/, ''
      query += "&#{k}=#{v}"  if v
    end
    query.gsub! /^&/, ''
    q_mark = query.present? ? ?? : ''
    target = [path, q_mark, query].join
  end
  if prefix
    return prefix  unless target.index ??
    target = target.gsub(/[^?]*(\?.*)/, prefix + '\1')
  end
  target
end

I would like some refactoring or speed optimizations.

Edit using URI and CGI:

I have a method to replace URL parameters in an URL. It receives url as mandatory parameter and prefix and/or hash as optional parameters. Examples:

The method:

I would like some refactoring or speed optimizations.

use URI ang CGI
Source Link
ujifgc
  • 215
  • 3
  • 7

Edit using URI and CGI:

def url_replace( target, *args )
  uri = URI.parse(URI.escape target)
  if hash = args.last.kind_of?(Hash) && args.last
    query = uri.query ? CGI.parse(uri.query) : {}
    hash.each do |k,v|
      v ? query[k.to_s] = v.to_s : query.delete(k.to_s)
    end
    uri.query = query.any? ? query.map{|k,v| "#{CGI.escape k.to_s}=#{CGI.escape Array(v).join}"}.join('&') : nil
  end
  prefix = args.first.kind_of?(String) && args.first
  uri.path = CGI.escape(prefix)  if prefix
  CGI.unescape(uri.to_s)
end

Edit using URI and CGI:

def url_replace( target, *args )
  uri = URI.parse(URI.escape target)
  if hash = args.last.kind_of?(Hash) && args.last
    query = uri.query ? CGI.parse(uri.query) : {}
    hash.each do |k,v|
      v ? query[k.to_s] = v.to_s : query.delete(k.to_s)
    end
    uri.query = query.any? ? query.map{|k,v| "#{CGI.escape k.to_s}=#{CGI.escape Array(v).join}"}.join('&') : nil
  end
  prefix = args.first.kind_of?(String) && args.first
  uri.path = CGI.escape(prefix)  if prefix
  CGI.unescape(uri.to_s)
end
Source Link
ujifgc
  • 215
  • 3
  • 7
Loading