首页 > 解决方案 > 当一些键是符号而其他键不是时,使哈希保持一致

问题描述

我使用此代码将 Matchdata 与 Hash 合并:

  params = {
    :url => 'http://myradiowebsite.com/thestation'
  }

  pattern = Regexp.new('^https?://(?:www.)?myradiowebsite.com/(?<station_slug>[^/]+)/?$')
  matchdatas = pattern.match(params[:url])
  #convert named matches in MatchData to Hash
  #https://stackoverflow.com/a/11690565/782013
  datas = Hash[ matchdatas.names.zip( matchdatas.captures ) ]

  params = params.merge(datas)

但这给了我参数哈希中的混合键:

{:url=>" http://myradiowebsite.com/thestation ", "station_slug"=>"thestation"}

稍后使用键获取哈希值是一个问题。我想将它们标准化为符号。

我正在学习 Ruby,如果这段代码有问题,谁能解释我,以及如何改进它?

谢谢 !

标签: regexrubyhash

解决方案


首先,请注意

pattern = 
  Regexp.new('^https?://(?:www.)?myradiowebsite.com/(?<station_slug>[^/]+)/?$')
  #=> /^https?:\/\/(?:www.)?myradiowebsite.com\/(?<station_slug>[^\/]+)\/?$/ 

我们获得

'http://wwwXmyradiowebsiteYcom/thestation'.match?(pattern)
   #=> true

这意味着需要转义之后'www'和之前的时期:'com'

pattern =
  Regexp.new('\Ahttps?://(?:www\.)?myradiowebsite\.com/(?<station_slug>[^/]+)/?\z')
  #=> /\Ahttps?:\/\/(?:www\.)?myradiowebsite\.com\/(?<station_slug>[^\/]+)\/?\z/ 

我还将行首锚 ( ^) 替换为字符串开头锚 ( \A),将行尾锚 ( $) 替换为字符串尾锚 ( \z),尽管两者都可以使用在这里,因为字符串由一行组成。

您在返回的哈希中获得了您想要的两个键::url:station_slug,所以对于

params = { :url => 'http://myradiowebsite.com/thestation' }

你可以计算

m = params[:url].match(pattern)
  #=> #<MatchData "http://myradiowebsite.com/thestation" station_slug:"thestation"> 

那么只要m不是nil(如这里),写

{ :url => m[0], :station_slug => m["station_slug"] }
  #=> {:url=>"http://myradiowebsite.com/thestation", :station_slug=>"thestation"}

请参阅MatchData#[]m[0]返回整个匹配;m["station_slug"]返回名为 的捕获组的内容"station_slug"

显然,捕获组的名称可以是任何有效的字符串,或者您可以将其设为未命名的捕获组并编写

{ :url => m[0], :station_slug => m[1] }

推荐阅读