2010-08-06 45 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|... 
    

    在反序列化無論何時你在兩個冒號或你認識的兩個管道字符,這是不是你的分隔符,但你的數據的一部分,你必須將其更改爲一個字符。另一方面,每一個冒號或管道字符都是你的分隔符。