我需要将Unicode字符串转换为带反斜杠的转义形式。 有谁知道该怎么做吗?
>> multi_byte_str = "hello\330\271!"
=> "hello\330\271!"
>> multi_byte_str.inspect
=> "\"hello\\330\\271!\""
>> puts multi_byte_str.inspect
"hello\330\271!"
=> nil
如果你想在 Ruby 1.9 中对多字节字符进行组件字节转义,你可能需要这么说:
>> multi_byte_str.bytes.to_a.map(&:chr).join.inspect
=> "\"hello\\xD8\\xB9!\""
如果你想获取已转义的unicode码点,无论是在Ruby 1.8还是1.9中,你都可以使用这种方法(尽管它也会转义可打印的内容):
>> multi_byte_str.unpack('U*').map{ |i| "\\u" + i.to_s(16).rjust(4, '0') }.join
=> "\\u0068\\u0065\\u006c\\u006c\\u006f\\u0639\\u0021"
#inspect
并不总是能给你所需的结果。#dump
应该可以解决问题。另外,请参考一个新的回答,我感到很有灵感写下了它。 - lindes"\u{1f92e}"
而不是"\u1f92e"
(这会得到ᾒe
)。 - Shelvacu要在Ruby中使用Unicode字符,请使用"\uXXXX"转义,其中XXXX是UTF-16代码点。请参见http://leejava.wordpress.com/2009/03/11/unicode-escape-in-ruby/
["XXXX".to_i(16)].pack("U*")
这行代码。该代码的作用是将十六进制字符串"XXXX"转为整数后,再打包成 Unicode 字符。 - Dave{
和 }
,例如 \u{1f60d}
表达了我发现如何表达这些事情的感觉。:D - lindes["1f60d".to_i(16)].pack("U*")
。这一点并不是显而易见的。 :) - Hakanairequire 'active_support'
x = ActiveSupport::JSON.encode('µ')
# x is now "\u00b5"
通常的非Rails JSON编码器不会将Unicode转换为"\u"。
String#dump
在Ruby中:String
对象中(或者可以轻松地将其放入其中),则只需在 repl 中显示字符串即可(取决于您的 Ruby 环境中 特定设置)。如果没有,您可以调用 #dump
方法。例如,有一个名为 unicode.txt
的文件,其中包含一些 UTF-8 编码的数据 - 比如货币符号 €£¥$
(加上换行符) - 运行以下代码(在 irb
中执行或作为脚本执行):s = File.read("unicode.txt", :encoding => "utf-8") # this may be enough, from irb
puts s.dump # this will definitely do it.
...应该打印出:
"\u20AC\u00A3\u00A5$\n"
€
是U+20AC,£
是U+00A3,¥
是U+00A5。($
未转换,因为它是纯ASCII,尽管技术上它是U+0024。如果您确实需要该信息,则可以修改下面的代码。或者只需在ASCII表中添加前导零 - 或引用已经这样做的表格。)
(注:上一个回答建议使用#inspect
而非#dump
。这种方法有时有效,但并非总是如此。例如,对于我来说,运行ruby -E UTF-8 -e 'puts "\u{1F61E}".inspect'
会打印出不高兴的脸,而不是转义序列。然而,将inspect
更改为dump
可以使我重新获得转义序列。)
String#encode
和rescue
:现在,如果您正在尝试对较大的输入文件进行上述操作,则以上内容可能会变得难以处理-在大多数ASCII文本中查找转义序列可能很困难,或者很难确定哪些序列与哪些字符相对应。在这种情况下,可以将上面的第二行替换为以下内容:
encodings = {} # hash to store mappings in
s.split("").each do |c| # loop through each "character"
begin
c.encode("ASCII") # try to encode it to ASCII
rescue Encoding::UndefinedConversionError # but if that fails
encodings[c] = $!.error_char.dump # capture a dump, mapped to the source character
end
end
# And then print out all the captured non-ASCII characters:
encodings.each do |char, dumped|
puts "#{char} encodes to #{dumped}."
end
€ encodes to "\u20AC".
£ encodes to "\u00A3".
¥ encodes to "\u00A5".
ў ў
,输出将是: encodes to "\u{1F64B}".
encodes to "\u{1F3FE}".
ў encodes to "\u045E".
у encodes to "\u0443". ̆
encodes to "\u0306".
实际上被编码为两个码点:一个基本字符(
- U+1F64B),带有一个修饰符(
, U+1F3FE; 参见)。同样的,对于其中之一的字母:ў
是单个预组合码点(U+045E),而第二个字母ў
- 尽管看起来相同 - 是通过将у
(U+0443)与修饰符 ̆
(U+0306)组合而成的,这可能无法正确呈现,包括在此页面上,因为它不是独立存在的。所以根据你的需求,你可能需要注意这些问题(我把它留给读者作为练习)。
或者,如果您有一封包含字符的电子邮件,并且您想查找编码的代码点值,如果您简单地搜索该字符,您通常会找到许多页面,其中列出了特定字符的unicode详细信息。例如,如果我做一个对✓
进行谷歌搜索, 我会得到,除其他外,一个wiktionary词条, 一个wikipedia页面和关于fileformat.info的页面,我发现这是一个获取特定unicode字符详细信息的有用网站。每个页面都列出了该勾选标记由unicode代码点U+2713表示的事实。(顺便说一句,在那个方向上搜索也很有效。)
同样地,可以搜索Unicode符号以匹配特定概念。例如,我以上搜索unicode check marks,即使在Google片段中也有几个代码点及其对应的图形列表,尽管我还发现了this list包含几个勾号符号,甚至有一个"list of useful symbols",其中包括各种勾号。
这同样适用于重音字符、表情符号等。只需搜索单词"unicode"以及您要查找的任何其他内容,您将倾向于获得包括列出代码点的页面的结果。然后,我们将把它放回到Ruby中:
Ruby字符串字面量文档介绍了两种将Unicode字符表示为转义序列的方法:
对于具有4位表示的码点,例如上面的U+2713,您可以将其输入为
\unnnn
表示Unicode字符,其中nnnn是4个十六进制数字([0-9a-fA-F])
\u{nnnn ...}
表示Unicode字符,每个nnnn都是1-6个十六进制数字([0-9a-fA-F])
\u2713
(在字符串文字中,该文字不用单引号)。对于任何Unicode字符(无论是否适合4位数),您都可以使用大括号({
和}
)括起来的完整十六进制值来编码代码点,例如\u{1f60d}
表示
。此形式还可用于在单个转义序列中编码多个代码点,使用空格分隔字符。例如,\u{1F64B 1F3FE}
会产生基本字符
和修饰符
,从而最终生成抽象字符
(如上所示)。€£¥$
)可以用\u{20AC A3 A5 24}
表示 - 对于其中三个字符仅需要2个数字。如果在文件的顶部添加#Encoding: UTF-8
,则可以直接使用unicode字符。然后您可以在源代码中自由地使用ä,ǹ,ú等字符。
试试这个宝石。它可以将Unicode或非ASCII标点符号和符号转换为最接近的ASCII标点符号和符号。
https://github.com/qwuen/punctuate
示例用法: "100٪".punctuate => "100%"
该宝石使用https://lexsrv3.nlm.nih.gov/LexSysGroup/Projects/lvg/current/docs/designDoc/UDF/unicode/DefaultTables/symbolTable.html中的参考进行转换。