如何删除ruby中不可打印/不可见的字符?

时间:2013-05-13 19:53:28

标签: ruby encoding non-printing-characters

有时我在字符串中间有邪恶的不可打印字符。这些字符串是用户输入的,所以我必须让我的程序很好地接收它,而不是试图改变问题的根源。

例如,他们可以在字符串的中间中使用zero width no-break space。例如,在解析.po文件时,一个有问题的部分是文件中间的字符串"he is a man of god"。虽然一切看起来都是正确的,但用irb检查它会显示:

 "he is a man of god".codepoints
 => [104, 101, 32, 105, 115, 32, 97, 32, 65279, 109, 97, 110, 32, 111, 102, 32, 103, 111, 100] 

我相信我知道BOM是什么,我甚至可以很好地处理它。但有时我在文件的中间有这样的字符,所以它不是BOM

我目前的做法是以一种非常臭的方式删除所有我发现邪恶的角色:

text = (text.codepoints - CODEPOINTS_BlACKLIST).pack("U*")

我得到的最接近的是关注this post,这导致我在regexp上:print:选项。然而这对我没有好处:

"m".scan(/[[:print:]]/).join.codepoints
 => [65279, 109] 

所以问题是:如何从ruby中的字符串中删除所有不可打印的字符?

3 个答案:

答案 0 :(得分:17)

试试这个:

>>"aaa\f\d\x00abcd".gsub(/[^[:print:]]/,'.')
=>"aaa.d.abcd"

答案 1 :(得分:2)

Ruby可以帮助您将一个多字节字符集转换为另一个字节集。查看search results,并阅读Ruby String的encode方法。

另外,Ruby的Iconv是你的朋友。

最后,James Gray写了一篇series of articles,详细介绍了这一点。

使用这些工具可以做的一件事就是告诉他们转码为视觉上相似的角色,或者完全忽略它们。

处理备用字符集是我曾经做过的最烦人的事情之一,因为文件可以包含任何内容,但可以标记为文本。你可能没想到它然后你的代码就会死掉或开始抛出错误,因为人们在提出将替代字符插入内容的方法时非常巧妙。

答案 2 :(得分:0)

代码点65279是zero-width no-break space。 通常用作byte-order mark (BOM)

您可以使用以下方法将其从字符串中删除:

my_new_string = my_old_string.gsub!("\xEF\xBB\xBF".force_encoding("UTF-8"), '')

检查是否有不可见字符的一种快速方法是检查字符串的长度,如果该长度大于在IRB中看到的长度,则执行此操作。