如何从字符串中删除不可打印的不可见字符?

时间:2019-04-25 14:21:51

标签: ruby string replace ruby-2.4

如何从字符串中删除不可打印的不可见字符?

Ruby版本: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我已经尝试了几种方法,但是如您所见,这些方法都没有帮助。

当我尝试与其他系统集成数据时,这会引起问题。

1 个答案:

答案 0 :(得分:4)

首先,让我们弄清楚什么是令人反感的人物:

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"),因此我们只需要google for U+202C

Google很快告诉我们,令人反感的字符是U+202C POP DIRECTIONAL FORMATTING,它是Unicode字符的“其他,格式”类别的成员。 Wikipedia says这个类别:

  

包括软连字符,连接控制字符(zwnj和zwj),支持双向文本的控制字符和语言标签字符

它还告诉我们类别的“值”或代码是“ Cf”。如果您想将这些听起来像字符的字符与U + 202C一起从字符串中删除,则可以在Ruby正则表达式中使用the \p{Cf} property。您还可以使用\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

请参见https://repl.it/@jrunning/DutifulRashTag