什么是从字符串中可靠地删除unicode的最佳方法

时间:2011-11-18 17:19:28

标签: ruby

我有各种各样的字符串,我需要从中提取'TM','(c)'等。这些标记是unicode。现在我只想把所有的unicode拉出来,一旦我开始工作,我会更有选择性,只需拔出法律标记。这是代码:

strings = ['Star Wars \u2122 2', 'Empire Strikes Back\u00C2\u00AE The Strikening',
       "Star Wars\u2122 2", "Empire Strikes Back\u00C2\\u00AE The Strikening"]

p strings.inspect

strings.each { |str|
  sub = str.gsub(/\\(u[(\d)a-fA-F]{4})/, "")
  p sub
}

结果:

["Star Wars \\u2122 2", "Empire Strikes Back\\u00C2\\u00AE The Strikening", "Star Wars\u2122 2", "Empire Strikes Back\u00C2\\u00AE The Strikening"]
"Star Wars  2"
"Empire Strikes Back The Strikening"
"Star Wars\u2122 2"
"Empire Strikes Back\u00C2 The Strikening"

适用于单引号,但不适用于双引号。我理解单引号字符串的行为与双引号字符串不同。这里的问题是,被送入此函数的字符串表现为双引号字符串并破坏代码(不会发生替换)。我尝试在gsub之前添加sub('\\', '\\\\')但是没有修复它。

我认为我误解了Ruby中字符串的行为方式。如何可靠地从"Star Wars\u2122 2"中删除unicode符号?我所拥有的正则表达式并没有这样做。

Ruby 1.9.3

2 个答案:

答案 0 :(得分:6)

这可能有点低效,因为它构建了一个包含每个字符的数组,但它可以工作(在Ruby 1.9及更高版本中):

s = "Empire Strikes Back\u00C2\u00AE The Strikening"
t = s.chars.select(&:ascii_only?).join    # => "Empire Strikes Back The Strikening"

当您编写'\u00C2'时,您没有创建包含unicode的字符串。您正在创建一个包含5个ASCII字符的字符串。当您编写"\u00C2"时,您正在创建一个包含单个非ASCII unicode字符的字符串。这是双引号表示法和单引号表示法之间的差异之一。

答案 1 :(得分:1)

只需'String with ™ and ®'.delete '™®'

另外,删除非ASCII字符的用例是什么?除非你正在做类似构建URL slug的事情,否则这可能不是一个好主意。如果您 构建一个URL slug,那么有很多宝石(例如friendly_id)将为您执行此操作。