从 ruby 中的 YAML 加载数据更改数据的 encoding/byte 结构?

Loading data from YAML in ruby changing the encoding/byte structure of data?

我正在尝试编写一种方法来使用 UTF-8 值删除一些列入黑名单的字符,例如 bom 字符。我通过使用以下逻辑在 String class 中创建 method 来成功实现此目的,

  def remove_blacklist_utf_chars
    self.force_encoding("UTF-8").gsub!(config[:blacklist_utf_chars][:zero_width_space].force_encoding("UTF-8"), "")
    self
  end

现在为了使它在应用程序中有用并可重复使用,我在 yml file 中创建了一个配置。 yml 结构类似于

:blacklist_utf_chars:
  :zero_width_space: '"\u{200b}"'

(Edit) 也正如 Drenmi 所建议的那样,这没有用,

:blacklist_utf_chars:
  :zero_width_space: \u{200b}

我面临的问题是,当我从yml file加载黑名单字符的utf编码时,方法remove_blacklist_utf_chars不起作用 但是当我直接在方法中传递这些而不是通过 yml file 时,该方法有效。

所以基本上
self.force_encoding("UTF-8").gsub!("\u{200b}".force_encoding("UTF-8"), "") -- 有效。

但是,

self.force_encoding("UTF-8").gsub!(config[:blacklist_utf_chars][:zero_width_space].force_encoding("UTF-8"), "") -- 无效。

我打印了 config[:blacklist_utf_chars][:zero_width_space] 的值,它等于 "\u{200b}"

这个想法是参考:.

现在我不确定在 ruby 代码中通过 yml 加载黑名单字符列表时到底发生了什么。

编辑 2:

在进一步调查中,我观察到在从 yaml 读取哈希时添加了一个额外的 \。 所以,

puts config[:blacklist_utf_chars][:zero_width_space].dump

打印:

"\u{200b}"

但是如果我将 yaml 定义为:

:blacklist_utf_chars:
  :zero_width_space: 200b

然后做,

ch = "\u{#{config[:blacklist_utf_chars][:zero_width_space]}}"
self.force_encoding("UTF-8").gsub!(ch.force_encoding("UTF-8"), "")

我明白了

/Users/harshsingh/dir/to/code/utils.rb:121: invalid Unicode escape (SyntaxError)

如果您 puts 值,并得到输出 "\u{200b}",这意味着引号包含在您的字符串中。也就是说,您实际上是在调用:

self.force_encoding("UTF-8").gsub!('"\u{200b}"'.config[:blacklist_utf_chars][:zero_width_space].force_encoding("UTF-8"), "")

尝试将您的 YAML 文件更改为:

:blacklist_utf_chars:
  :zero_width_space: \u{200b}

"\u{200b}" 语法用于转义 Ruby 源代码 中的 Unicode 字符。它在 Yaml.

中不起作用

中的equivalent syntax for a Yaml document is the similar "\u200b" (which also happens to be valid in Ruby). Note the lack of braces ({}), and also the double quotes are required,否则会被解析为字面量\u200b

因此您的 Yaml 文件应如下所示:

:blacklist_utf_chars:
  :zero_width_space: "\u200b"