Символы для разделения значения - PullRequest
0 голосов
/ 07 августа 2010

Мне нужно создать строку для хранения пар данных ключ / значение, например:

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

при десериализации я могу столкнуться с ошибкой, если ключ или значение содержат || или ::

Каковы общие методы, чтобы справиться с такой ситуацией? спасибо

Ответы [ 7 ]

2 голосов
/ 07 августа 2010

Обычный способ справиться с этим называется escape-символом или квалификатором. Рассмотрим эту разделенную запятыми строку:

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

Поскольку поле имени содержит запятую, оно, конечно, неправильно разделяется и т. Д.

Если вы заключаете каждое значение данных в классификаторы, парсер знает, когда игнорировать разделитель, как в этом примере:

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

Квалификаторы могут быть необязательными и использоваться только в тех полях данных, которые в них нуждаются. Многие реализации будут использовать квалификаторы в каждом поле, нужно это или нет.

Возможно, вы захотите реализовать нечто подобное для вашей кодировки данных.

1 голос
/ 07 августа 2010

Если мы предполагаем, что у вас есть полный контроль над входной строкой, то обычным способом решения этой проблемы является использование escape-символа.

Как правило, символ обратной косой черты - \ используется как escapeсказать, что «следующий символ является специальным символом», поэтому в этом случае его не следует использовать в качестве разделителя.Таким образом, синтаксический анализатор будет видеть || и :: как разделители, но будет видеть \|\| как два символа канала || в ключе или в значении.

Следующая проблема заключается в том, что мы перегруженыобратный слешПроблема в том, «как мне представить обратную косую черту».Это подтверждается тем, что обратная косая черта также экранирована, поэтому для обозначения \ вы должны будете сказать \\.Поэтому синтаксический анализатор будет видеть \\ как \.

Обратите внимание, что если вы используете escape-символы, вы можете использовать один символ для разделителей, что может упростить задачу.

В качестве альтернативыВам, возможно, придется ограничить ввод и сказать, что || и :: просто запрещены и дают сбой / удаление при кодировании строки.

1 голос
/ 07 августа 2010

Escape || при сериализации и удаление при десериализации.Распространенный C-подобный способ избежать - это предвосхитить \.Например:

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

Обратите внимание, что \ необходимо экранировать (и дважды экранировать из-за помещения в строку в стиле C).

0 голосов
/ 07 августа 2010

Вы можете использовать не-ascii символ в качестве разделителя (например, вертикальная табуляция :-)).

Вы можете экранировать символ-разделитель в ваших данных во время сериализации. Например: если вы используете один символ в качестве разделителя (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|...

Во время десериализации, когда вы сталкиваетесь с двумя символами двоеточия или двумя символами канала, вы знаете, что это не ваш разделитель, а часть ваших данных, и вам нужно изменить его на один символ. С другой стороны, каждый символ двоеточия или канала - это разделитель.

0 голосов
/ 07 августа 2010

Используйте префикс (скажем «a») для ваших специальных символов (скажем, «b»), присутствующих в ключе, и значения для их хранения. Это называется escape .

Затем декодируйте ключ и значения, просто заменив любую последовательность «ab» на «b». Имейте в виду, что префикс также является специальным символом . Пример:

Префикс: \

Специальные символы: :, |, \

закодированные:

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

Расшифровано:

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

shortTitle = \.

0 голосов
/ 07 августа 2010

Простым решением является отключение разделителя (например, с обратной косой чертой) каждый раз, когда он встречается в данных:

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

Конечно, разделитель необходимо будет экранировать, когда он встречается и в данных; в этом случае обратная косая черта станет \\.

0 голосов
/ 07 августа 2010

Обычная техника - экранирование зарезервированных символов, например:

  • В URL вы экранируете некоторые символы, используя представление% HEX: http://example.com? Aa = a% 20b

  • В языках программирования экранирование некоторых символов осуществляется с префиксом косой черты: "\" hello \ ""

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...