Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从ruby中取消显示c风格的转义序列?_Ruby - Fatal编程技术网

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

如何从ruby中取消显示c风格的转义序列?,ruby,Ruby,在ruby中,如何解码c风格的转义序列?e、 g.“\n”到换行符,“\t”到制表符?更短,更黑,更危险,因为评估: eval“\”{string}\” 一个简单的例子: >a='1\t2\n3' >提出 1\t2\n3 >将求值“\”{a}”放入 1 2 3. 编辑:请注意,这实际上不起作用。您确实需要在这里使用状态机构建一个适当的解析器,该状态机跟踪您是否处于转义序列中 Ruby支持许多相同的转义序列,因此您可以构建一个简单的转换表,如下所示: T = { '\n' =&

在ruby中,如何解码c风格的转义序列?e、 g.“\n”到换行符,“\t”到制表符?

更短,更黑,更危险,因为评估:
eval“\”{string}\”
一个简单的例子:

>a='1\t2\n3'
>提出
1\t2\n3
>将求值“\”{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"

好的,如果您不喜欢
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

以下代码将正确解码ISO-C标准定义的所有转义序列。这是节省和合理的性能:

ISO_C_ESCAPE_SEQUENCES = %r{
    # One letter escapes
    (?:\\[abfnrtv\\'"?])

    # Hex encoded character
    | (?:\\(x)([A-Fa-f0-9]{2,}))

    # Any Unicode code point (8 hex digits) or
    # Unicode code point below 1000 (4 hex digits)
    | (?:\\(u)((?:[A-Fa-f0-9]{8})|(?:[A-Fa-f0-9]{4})))

    # Octal encoded character
    | (?:\\([0-7]{1,3}))
}x


ISO_C_ONE_LETTER_ESCAPES = {
    "\\a"  => "\a",
    "\\b"  => "\b",
    "\\f"  => "\f",
    "\\n"  => "\n",
    "\\r"  => "\r",
    "\\t"  => "\t",
    "\\v"  => "\v",
    "\\\\" => "\\",
    "\\'"  => "'",
    "\\\"" => "\"",
    "\\?"  => "?"
}


def decodeCString( cString )
    return cString.gsub(ISO_C_ESCAPE_SEQUENCES) { |match|
        replacement = ISO_C_ONE_LETTER_ESCAPES[match]
        next replacement if replacement
        next $2.to_i(16).chr if $1 == "x"
        next $4.to_i(16).chr(Encoding::UTF_8) if $3 == "u"
        next $5.to_i(8).chr
    }
end
以下是一个示例:

puts decodeCString("Line \\\\n Same Line!\\nNew line\\x0ANew line")
puts decodeCString("Smiley: \\u263A\tHorse head: \\u00010083")
puts decodeCString("Equal sign in quotes: \\\"\\75\\\"")
印刷品

Line\n同一行!
新线
新线

斯迈利:☺ 马头:也不行;解析“\n”结构比搜索和替换要困难一些-您必须首先注意转义序列的转义。事实上,一行一个字节地去做要容易得多。不过我喜欢你用
T
做的事情!
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
ISO_C_ESCAPE_SEQUENCES = %r{
    # One letter escapes
    (?:\\[abfnrtv\\'"?])

    # Hex encoded character
    | (?:\\(x)([A-Fa-f0-9]{2,}))

    # Any Unicode code point (8 hex digits) or
    # Unicode code point below 1000 (4 hex digits)
    | (?:\\(u)((?:[A-Fa-f0-9]{8})|(?:[A-Fa-f0-9]{4})))

    # Octal encoded character
    | (?:\\([0-7]{1,3}))
}x


ISO_C_ONE_LETTER_ESCAPES = {
    "\\a"  => "\a",
    "\\b"  => "\b",
    "\\f"  => "\f",
    "\\n"  => "\n",
    "\\r"  => "\r",
    "\\t"  => "\t",
    "\\v"  => "\v",
    "\\\\" => "\\",
    "\\'"  => "'",
    "\\\"" => "\"",
    "\\?"  => "?"
}


def decodeCString( cString )
    return cString.gsub(ISO_C_ESCAPE_SEQUENCES) { |match|
        replacement = ISO_C_ONE_LETTER_ESCAPES[match]
        next replacement if replacement
        next $2.to_i(16).chr if $1 == "x"
        next $4.to_i(16).chr(Encoding::UTF_8) if $3 == "u"
        next $5.to_i(8).chr
    }
end
puts decodeCString("Line \\\\n Same Line!\\nNew line\\x0ANew line")
puts decodeCString("Smiley: \\u263A\tHorse head: \\u00010083")
puts decodeCString("Equal sign in quotes: \\\"\\75\\\"")