2010-08-06 49 views
0

我需要创建一个字符串存储键/值数据的夫妇,例如:字符到单独的值

key1::value1||key2::value2||key3::value3 

在反序列化它,我可能会遇到一个错误,如果键或值碰巧含有||::

什么是常见的技术来处理这种情况?谢谢

回答

2

解决此问题的常见方法称为转义字符或限定符。考虑这个逗号分隔行:

Name,City,State 
John Doe, Jr.,Anytown,CA 

因为名称字段包含一个逗号,这当然被不当等分裂。

如果你包围由预选赛每个数据值,解析器知道何时忽略分隔符,如下例所示:

Name,City,State 
"John Doe, Jr.",Anytown,CA 

预选赛可以是可选的,只在需要它的数据字段使用。许多实现将在每个字段上使用限定符,无论是否需要。

你可能想为你的数据编码实现类似的东西。

0

的常用技术是逸出保留字符,例如: http://example.com?aa=a%20b

  • 在编程语言中你逃脱 一些与字符:

    • 在URL中您使用%HEX表示逸出一些字符 斜线前缀: “\”hello \“”

  • 0

    一个简单的解决方案是将逸出的隔板(用反斜杠,例如)它在数据中出现的任何时间:

    Name,City,State 
    John Doe\, Jr.,Anytown,CA

    当然,分离器将需要当在数据中出现它,以及进行转义;在这种情况下,反斜杠将变为\\

    0

    使用前缀(比如说“a”)来表示键中存在的特殊字符(比如说“b”)和存储它们的值。这被称为转义

    然后通过简单地用“b”替换任何“ab”序列来解码密钥和值。 请注意,前缀也是特殊字符。一个例子:

    前缀:\

    特殊字符::|\

    编码:

    title:Slashdot\: News for Nerds. Stuff that Matters.|shortTitle:\\.

    解码:

    title = Slashdot: News for Nerds. Stuff that Matters.

    shortTitle = \.

    1

    逃逸||串行化时,和UNESCAPE它反序列化时。一种常见的类似于C的方法是前置\。例如:

    { "a:b:c": "foo||bar", "asdf": "\\|||x||||:" } 
    serialize => "a\:b\:c:foo\|\|bar||asdf:\\\\\|\|\|x\|\|\|\|\:" 
    

    注意\需要被转义(和双转义由于被放置在C语言风格的字符串)。

    1

    如果我们假设您对输入字符串有完全控制权,那么处理这个问题的常用方法是使用转义字符。

    通常,反斜杠\ \字符被用作转义来说“下一个字符是特殊字符”,所以在这种情况下,它不应该被用作分隔符。因此,解析器将会看到||::作为分隔符,但会将\|\|视为密钥或值中的两个管道字符||

    接下来的问题是我们重载了反斜杠。那么问题是,“我如何表示反斜杠”。这被说反斜杠也逃脱了,所以代表一个\,你不得不说\\。所以解析器将会看到\\\

    请注意,如果您使用转义字符,则可以使用单个字符作为分隔符,这可能会使事情变得更简单。

    或者,您可能必须恢复输入,并说||::只是被放置并且在编码字符串时失败/删除。

    0

    您可以使用非ASCII字符作为分隔符(例如vertical tab :-))。

    在序列化期间,您可以在数据中转义分隔符。例如:如果你使用一个字符作为分隔符(key1:value1|key2:value2|...)和你的数据是:

    this:is:key1 this|is|data1 
    this:is:key2 this|is|data2 
    

    你双击你的数据每冒号和竖线,当你把它序列化。所以,你会得到:

    this::is::key1:this||is||data1|this::is::key2:this||is||data2|... 
    

    在反序列化无论何时你在两个冒号或你认识的两个管道字符,这是不是你的分隔符,但你的数据的一部分,你必须将其更改为一个字符。另一方面,每一个冒号或管道字符都是你的分隔符。