Use a standard URI parser to break this problem into smaller parts. Let a modern URI library worry about arcane details like spaces, fragments, userinfo, IPv6 hosts, etc.
uri = URI.parse(target).normalize
uri.absolute? or raise 'URI not absolute'
%w[ http https ftp ].include?(uri.scheme) or raise 'Unsupported URI scheme'
# Etc
That was not an option in this case, as the goal is to validate URLs entered as user input and blacklist certain URL constructs even though they’re technically valid.