【问题标题】:How to remove non-printable/invisible characters in ruby?如何删除 ruby​​ 中的不可打印/不可见字符?
【发布时间】:2025-12-24 12:05:16
【问题描述】:

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

例如,它们可以在字符串的中间中包含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,这使我找到了正则表达式上的:print: 选项。然而这对我没有好处:

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

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

【问题讨论】:

  • 如果您显示更多包含您要处理的字符的源字符串和示例字符串,将会有很大帮助。当前示例在尝试确定代码集或您遇到的其他值时没有多大帮助。
  • @theTinMan 谢谢,我用更多细节编辑了这个问题。字符集是 UTF-8,我相信,但我并不总是有信息,我有很多没有 BOM 的文件。这个我想通过查看中文翻译,它至少部分是 unicode。
  • Ruby 在 String 上有一个名为 dump 的方法,它会生成一个新字符串,其中删除了非打印字符并转义了特殊字符。 String#dump Ruby 2.3.0 的文档,但我可以确认它早在 1.8.7 的文档中。

标签: ruby encoding non-printing-characters


【解决方案1】:

试试这个:

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

【讨论】:

  • 不幸的是,这也删除了换行符。
【解决方案2】:

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

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

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

您可以使用这些工具执行的其中一项操作是告诉它们转码为视觉上相似的字符,或者完全忽略它们。

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

【讨论】:

  • 放弃.. 我认为没有更好的方法来处理格式错误的文件。不过,我接受了您的回答,因为对于最终获得格式良好的文件的人来说,这是一个很好的指南。
  • 这些链接现在都不起作用:(
  • @Surya,谢谢,是的,有几个坏了,但不是全部。 SO方式是帮助维护站点。您有权通过提交编辑来修复链接断开等问题来提供帮助。请参阅“How do suggested edits work”。
  • 感谢您提醒我注意此功能。
【解决方案3】:

代码点 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 中看到的长度,则可以。

【讨论】: