【问题标题】:How best to get all the format sequence keys from a string in ruby?如何最好地从 ruby​​ 中的字符串中获取所有格式序列键?
【发布时间】:2022-12-11 20:21:09
【问题描述】:

当给定一个字符串,该字符串打算使用要写入字符串的散列值进行格式化时,是否有一种干净的方法来获取字符串期望值的所有键?

我在有很大自定义空间的情况下将文本放在一起,并且有几个动态值选项可以插入到文本中。有些值比其他值更昂贵,所以我希望能够准备我的散列以发送到 % 以仅包含字符串中需要的值。

理想情况下,我能够查询对字符串执行格式设置的系统,但我没有看到此类接口的任何文档。我想要的是这样的:

"Your request for %{item} is at position %<pos>d".formatting_keys
>>> [:item, :pos]

【问题讨论】:

  • %{item}不是插值,是format sequence
  • 谢谢,我已经更新了措辞

标签: ruby


【解决方案1】:

我希望能够准备我的散列以发送到 % 以仅包含字符串中需要的值。

使用一个按需计算的对象,而不是哈希。这将在任何地方都有用。

使用字符串插值来调用方法而不是格式化序列。

class Whatever
  def item
    @item ||= calculate_item
  end

  def pos
    @pos ||= calculate_pos
  end

  private

  def calculate_item
    # do something expensive
  end

  def calculate_pos
    # do something expensive
  end
end

obj = Whatever.new
puts "Your request for #{obj.item} is at position #{obj.pos.to_i}"

【讨论】:

  • 我意识到我将其描述为插值,但这实际上并不是我想要做的,我需要使用字符串作为格式规范。但是,也许我可以创建一个对象(或在散列上定义一个默认过程)来延迟加载值,并将其发送到%
【解决方案2】:

将哈希传递给 String#% 时,如果缺少密钥,它将调用哈希的 default proc。您可以利用此行为并让 proc 偷偷收集传递的密钥:

def format_keys(format_string)
  keys = []
  format_string % Hash.new { |_, k| keys << k ; 0 }
  keys
end

format_keys("Your request for %{item} is at position %<pos>d")
#=> [:item, :pos]

请注意,proc 的返回值必须是各种字段类型的有效对象。我在这里使用 0 似乎工作正常。

【讨论】:

  • 啊,聪明,谢谢!
【解决方案3】:

根据 https://stackoverflow.com/a/74728162 使用 Ruby 自己的序列解析是理想的,但你也可以自己做:

class String
  def format_keys
    scan(
      /
        (?<!%) # don't match escaped sequence starts, e.g. "%%{"
        (?:
          (?<=%{) [^}]+ (?=}) # contents of %{...}
          |                      # OR
          (?<=%<) [^>]+ (?=>) # contents of %<...>
        )
      /x
    )
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 2016-08-08
    • 1970-01-01
    相关资源
    最近更新 更多