我需要创建一个字符串存储键/值数据的夫妇,例如:字符到单独的值
key1::value1||key2::value2||key3::value3
在反序列化它,我可能会遇到一个错误,如果键或值碰巧含有||
或::
什么是常见的技术来处理这种情况?谢谢
我需要创建一个字符串存储键/值数据的夫妇,例如:字符到单独的值
key1::value1||key2::value2||key3::value3
在反序列化它,我可能会遇到一个错误,如果键或值碰巧含有||
或::
什么是常见的技术来处理这种情况?谢谢
解决此问题的常见方法称为转义字符或限定符。考虑这个逗号分隔行:
Name,City,State
John Doe, Jr.,Anytown,CA
因为名称字段包含一个逗号,这当然被不当等分裂。
如果你包围由预选赛每个数据值,解析器知道何时忽略分隔符,如下例所示:
Name,City,State
"John Doe, Jr.",Anytown,CA
预选赛可以是可选的,只在需要它的数据字段使用。许多实现将在每个字段上使用限定符,无论是否需要。
你可能想为你的数据编码实现类似的东西。
的常用技术是逸出保留字符,例如: http://example.com?aa=a%20b
在编程语言中你逃脱 一些与字符:
在URL中您使用%HEX表示逸出一些字符 斜线前缀: “\”hello \“”
一个简单的解决方案是将逸出的隔板(用反斜杠,例如)它在数据中出现的任何时间:
Name,City,State John Doe\, Jr.,Anytown,CA
当然,分离器将需要当在数据中出现它,以及进行转义;在这种情况下,反斜杠将变为\\
。
使用前缀(比如说“a”)来表示键中存在的特殊字符(比如说“b”)和存储它们的值。这被称为转义。
然后通过简单地用“b”替换任何“ab”序列来解码密钥和值。 请注意,前缀也是特殊字符。一个例子:
前缀:\
特殊字符::
,|
,\
编码:
title:Slashdot\: News for Nerds. Stuff that Matters.|shortTitle:\\.
解码:
title
= Slashdot: News for Nerds. Stuff that Matters.
shortTitle
= \.
逃逸||
串行化时,和UNESCAPE它反序列化时。一种常见的类似于C的方法是前置\
。例如:
{ "a:b:c": "foo||bar", "asdf": "\\|||x||||:" }
serialize => "a\:b\:c:foo\|\|bar||asdf:\\\\\|\|\|x\|\|\|\|\:"
注意\
需要被转义(和双转义由于被放置在C语言风格的字符串)。
如果我们假设您对输入字符串有完全控制权,那么处理这个问题的常用方法是使用转义字符。
通常,反斜杠\ \字符被用作转义来说“下一个字符是特殊字符”,所以在这种情况下,它不应该被用作分隔符。因此,解析器将会看到||
和::
作为分隔符,但会将\|\|
视为密钥或值中的两个管道字符||
。
接下来的问题是我们重载了反斜杠。那么问题是,“我如何表示反斜杠”。这被说反斜杠也逃脱了,所以代表一个\
,你不得不说\\
。所以解析器将会看到\\
为\
。
请注意,如果您使用转义字符,则可以使用单个字符作为分隔符,这可能会使事情变得更简单。
或者,您可能必须恢复输入,并说||
和::
只是被放置并且在编码字符串时失败/删除。
您可以使用非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|...
在反序列化无论何时你在两个冒号或你认识的两个管道字符,这是不是你的分隔符,但你的数据的一部分,你必须将其更改为一个字符。另一方面,每一个冒号或管道字符都是你的分隔符。