我将以下十六进制作为字符串:"\xfe\xff"
。我想将其转换为"feff"
。我该怎么做呢?
我最接近的是"\xfe\xff".inspect.gsub("\\x", "")
,返回"\"FEFF\""
。
答案 0 :(得分:9)
"\xfe\xff".unpack("H*").first
# => "feff"
答案 1 :(得分:4)
您正在处理双引号字符串中的转义序列。双引号字符串中最常见的转义序列是“\ n”,但ruby允许您在字符串中使用其他转义序列。您的字符串“\ xfe \ xff”包含两个十六进制转义序列,其格式为:
\xNN
转义序列代表一个字符。当ruby处理字符串时,它会注意到“\”并将整个十六进制转义序列转换为一个字符。在ruby处理字符串之后,字符串中的任何位置都没有\ x。因此,在字符串中查找\ x是徒劳的 - 它不存在。对于转义序列中的字符'f'和'e'也是如此:在ruby处理字符串后,字符串中不存在它们。
请注意,ruby仅处理双引号字符串中的十六进制转义序列,因此字符串的类型(双引号或单引号)完全相关。在单引号字符串中,字符系列'\ xfe'的长度为四个字符,因为在单个带引号的字符串中没有十六进制转义序列:
str = "\xfe"
puts str.length #=>1
str = '\xfe'
puts str.length #=>4
正则表达式的行为类似于双引号字符串,因此可以在正则表达式中使用整个转义序列:
/\xfe/
当ruby处理正则表达式时,就像使用双引号字符串一样,ruby将十六进制转义序列转换为单个字符。这允许您在包含相同十六进制转义序列的字符串中搜索单个字符:
if "abc\xfe" =~ /\xfe/
如果假装一分钟,字符ruby将转义序列“\ xfe”转换为字符'z',则该if语句等效于:
if "abcz" =~ /z/
重要的是要认识到正则表达式不会在字符串中搜索“\”后跟“x”后跟“f”后跟“e”。字符串中不存在这些字符。
inspect()方法允许您通过使转义序列无效来查看字符串中的转义序列,如下所示:
str = "\\xfe\\xff"
puts str
--output:--
\xfe\xff
在双引号字符串中,"\\"
表示文字反斜杠,而转义序列仅以一个斜杠开头。
一旦你使转义序列无效,你就可以匹配文字字符,比如两个字符序列'\ x'。但是更容易选择你想要的部件而不是匹配你不想要的部件:
str = "\xfe\xff"
str = str.inspect #=> "\"\\xFE\\xFF\""
result = ""
str.scan /x(..)/ do |groups_arr|
result << groups_arr[0]
end
puts result.downcase
--output:--
feff
这是gsub:
str = "\xfe\xff"
str = str.inspect #=>"\"\\xFE\\xFF\""
str.gsub!(/
"? #An optional quote mark
\\ #A literal '\'
x #An 'x'
(..) #Any two characters, captured in group 1
"? #An optional quote mark
/xm) do
Regexp.last_match(1)
end
puts str.downcase
--output:--
feff
请记住,正则表达式的作用类似于双引号字符串,因此要在正则表达式中指定文字\,您必须编写\\
。但是,在正则表达式中,您不必担心"
被误认为正则表达式的结尾,因此您不需要像使用双引号字符串那样将其转义。
只是为了好玩:
str = "\xfe\xff"
result = ""
str.each_byte do |int_code|
result << sprintf('%x', int_code)
end
p result
--output:--
"feff"
答案 2 :(得分:0)
你为什么要打电话检查?那是添加额外的报价..
另外,将它放在双引号中意味着\ x被内插。把它放在单引号中,一切都应该是好的。
'\xfe\xff'.gsub("\\x","")
=> "feff"