从字符串中删除十字转义

时间:2013-08-25 04:33:20

标签: ruby regex

我将以下十六进制作为字符串:"\xfe\xff"。我想将其转换为"feff"。我该怎么做呢?

我最接近的是"\xfe\xff".inspect.gsub("\\x", ""),返回"\"FEFF\""

3 个答案:

答案 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" 
相关问题