jro*_*ind 25 ruby character-encoding
我有一个我从某种输入中读过的字符串.
据我所知,它是UTF8.好的:
string.force_encoding("utf8")
Run Code Online (Sandbox Code Playgroud)
但是如果这个字符串中包含的字节实际上不是合法的UTF8,我现在想知道并采取行动.
通常,如果遇到这样的字节,force_encoding("utf8")会提高吗?我相信它不会.
如果我正在做#encode,我可以从方便的选项中选择如何处理源编码(或目标编码)中无效的字符.
但是我没有做#encode,我正在做一个#force_encoding.它没有这样的选择.
它会有意义吗?
string.force_encoding("utf8").encode("utf8")
Run Code Online (Sandbox Code Playgroud)
马上得到一个例外?通常从 utf8 到 utf8的编码没有任何意义.但是,如果存在无效字节,这可能是让它立即提升的方法吗?或者使用:replace选项etc来执行与无效字节不同的操作?
但是,不,似乎也无法做到这一点.
谁知道?
1.9.3-p0 :032 > a = "bad: \xc3\x28 okay".force_encoding("utf-8")
=> "bad: \xC3( okay"
1.9.3-p0 :033 > a.valid_encoding?
=> false
Run Code Online (Sandbox Code Playgroud)
好的,但我如何找到并消除那些坏字节?奇怪的是,这不会引起:
1.9.3-p0 :035 > a.encode("utf-8")
=> "bad: \xC3( okay"
Run Code Online (Sandbox Code Playgroud)
如果我转换为不同的编码,它会!
1.9.3-p0 :039 > a.encode("ISO-8859-1")
Encoding::InvalidByteSequenceError: "\xC3" followed by "(" on UTF-8
Run Code Online (Sandbox Code Playgroud)
或者,如果我告诉它,它会用"?"代替它.=>
1.9.3-p0 :040 > a.encode("ISO-8859-1", :invalid => :replace)
=> "bad: ?( okay"
Run Code Online (Sandbox Code Playgroud)
因此,当转换为不同的编码时,ruby有智能知道utf-8中的坏字节,并用其他东西替换em.但我不想转换为不同的编码,我想保留utf8 - 但如果那里有一个无效字节,我可能想要提高,或者我可能想用替换字符替换无效字节.
是不是有办法让红宝石这样做?
更新我相信这最终已经添加到2.1中的ruby,在2.1预览版本中使用String#scrub来执行此操作.所以寻找它!
jro*_*ind 16
(更新:请参阅https://github.com/jrochkind/scrub_rb)
所以我编写了一个我需要的解决方案:https://github.com/jrochkind/ensure_valid_encoding/blob/master/lib/ensure_valid_encoding.rb
但是最近才知道这实际上已经内置到stdlib中,你只需要在某种程度上反直觉地将'binary'作为"源代码编码":
a = "bad: \xc3\x28 okay".force_encoding("utf-8")
a.encode("utf-8", "binary", :undef => :replace)
=> "bad: ?( okay"
Run Code Online (Sandbox Code Playgroud)
是的,这正是我想要的.事实证明这个IS内置于1.9 stdlib,它只是没有文档,很少有人知道它(或者很少有人说英语知道它?).虽然我看到这些论点在某个地方的博客上以这种方式使用,所以其他人都知道它!
| 归档时间: |
|
| 查看次数: |
21885 次 |
| 最近记录: |