我如何从ruby中取消c风格的转义序列?

在ruby中,如何解码c风格的转义序列? 例如’\ n’到换行符,’\ t’到标签?

好的,如果你不喜欢eval解决方案,我在Ruby中破解了一个简单的状态机来正确解析字符串中的简单“\ n”和“\ t”,包括反斜杠本身的预迁移。 这里是:

 BACKSLASH = "\\" def unescape_c_string(s) state = 0 res = '' s.each_char { |c| case state when 0 case c when BACKSLASH then state = 1 else res << c end when 1 case c when 'n' then res << "\n"; state = 0 when 't' then res << "\t"; state = 0 when BACKSLASH then res << BACKSLASH; state = 0 else res << BACKSLASH; res << c; state = 0 end end } return res end 

这个可以很容易地扩展,以支持更多的字符,包括多字符实体,如\123 。 测试单位certificate它有效:

 require 'test/unit' class TestEscapeCString < Test::Unit::TestCase def test_1 assert_equal("abc\nasd", unescape_c_string('abc\nasd')) end def test_2 assert_equal("abc\tasd", unescape_c_string('abc\tasd')) end def test_3 assert_equal("abc\\asd", unescape_c_string('abc' + BACKSLASH * 2 + 'asd')) end def test_4 assert_equal("abc\\nasd", unescape_c_string('abc' + BACKSLASH * 2 + 'nasd')) end def test_5 assert_equal("abc\\\nasd", unescape_c_string('abc' + BACKSLASH * 3 + 'nasd')) end def test_6 assert_equal("abc\\\\nasd", unescape_c_string('abc' + BACKSLASH * 4 + 'nasd')) end end 

由于评估,更短,更黑,更危险:

  eval“\”#{string} \“” 

一个简单的例子:

 > a ='1 \ t2 \ n3'
 >放一个
 1个\ T2 \ N3
 > put eval“\”#{a} \“”
 1 2
 3

编辑:请注意,这实际上不起作用。 你真的需要在这里建立一个适当的解析器,状态机可以跟踪你是否处于转义序列中。


Ruby支持许多相同的转义序列,因此您可以构建一个简单的转换表,如下所示:

 T = { '\n' => "\n", '\t' => "\t", '\r' => "\r" } 

然后使用该转换表替换源字符串中的那些序列:

 a = '1\t2\n3' a.gsub(/#{T.keys.map(&Regexp.method(:escape)).join('|')}/, &T.method(:[])) # => "1\t2\n3"