如何从字符串中删除不可打印的不可见字符?
拼音版本:2.4.1
2.4.1 :209 > product.name.gsub(/[^[:print:]]/,'.')
=> "Kanha"
2.4.1 :210 > product.name.gsub(/[^[:print:]]/,'.').length
=> 6
2.4.1 :212 > product.name.gsub(/[u0080-u00ff]/, '').length
=> 6
2.4.1 :214 > product.name.chars.reject { |char| char.ascii_only? and (char.ord < 32 or char.ord == 127) }.join.length
=> 6
2.4.1 :216 > product.name.gsub(/[^[:print:]]/i, '').length
=> 6
"Kanha"这个词有5个字母。但是,第 6 个字符不可打印。如何删除它?
通过谷歌搜索和SOing,我已经尝试了一些方法,但正如你所看到的,这些方法都没有帮助。
当我尝试将数据与其他系统集成时,它会导致问题。
首先,让我们弄清楚冒犯字符是什么:
str = "Kanha"
p str.codepoints
# => [75, 97, 110, 104, 97, 8236]
前五个代码点介于 0 和 127 之间,这意味着它们是 ASCII 字符。可以安全地假设它们是字母 K-a-n-h-a,尽管如果您愿意,这很容易验证:
p [75, 97, 110, 104, 97].map(&:ord)
# => ["K", "a", "n", "h", "a"]
这意味着违规字符是最后一个,代码点 8236。但是,这是一个十进制(以 10 为基数)的数字,Unicode 字符通常按其十六进制(以 16 为基数)列出。十六进制中的 8236 是 202C (8236.to_s(16) # => "202c"
),所以我们只需要谷歌搜索 U+202C。
谷歌很快告诉我们,有问题的字符是U + 202C流行方向格式,并且它是Unicode字符的"其他,格式"类别的成员。维基百科说这个类别:
包括软连字符、连接控制字符(zwnj 和 zwj)、支持双向文本的控制字符和语言标记字符
它还告诉我们类别的"值"或代码是"Cf"。如果这些听起来像您希望与 U+202C 一起从字符串中删除的字符,则可以在 Ruby 正则表达式中使用p{Cf}
属性。您也可以使用P{Print}
(注意大写字母P
)作为等效于[^[:print]]
:
str = "Kanha"
p str.length # => 6
p str.gsub(/P{Print}|p{Cf}/, '') # => "Kahna"
p str.gsub(/P{Print}|p{Cf}/, '').length # => 5
在 repl.it 上看到它:https://repl.it/@jrunning/DutifulRashTag