Наименее используемый символ-разделитель в обычном тексте <ASCII 128 - PullRequest
64 голосов
/ 29 января 2009

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

Я разделю их, используя символ.

Какой символ лучше всего использовать для этого, то есть какой символ наименее вероятно появится в тексте? Должно быть напечатано и, вероятно, меньше 128 в ASCII, чтобы избежать проблем с локалью.

Ответы [ 16 ]

29 голосов
/ 29 января 2009

Предполагая, что по какой-то неловкой причине вы не можете использовать CSV, я бы сказал, что нужно идти с данными Возьмите некоторые примерные данные и выполните простой подсчет символов для каждого значения 0-127. Выберите один из тех, которые не встречаются. Если есть слишком много выбора, получите больший набор данных. Писать не займет много времени, и вы получите лучший ответ для вас.

Ответ будет различным для разных проблемных областей, поэтому | (pipe) распространен в сценариях оболочки, ^ - в математических формулах, и то же самое, вероятно, верно для большинства других символов.

Я лично думаю, что пойду на | (труба), если есть выбор, но с реальными данными безопаснее всего.

И что бы вы ни делали, убедитесь, что вы разработали схему побега!

17 голосов
/ 29 января 2009

Возможно | или ^ или ~ вы также можете объединить два символа

14 голосов
/ 09 января 2017

Я бы выбрал «разделитель единиц» ascii код «US», ascii 30 (0x1F)

В старые, старые времена большинство вещей делалось поочередно, без произвольного доступа. Это означало, что в ASCII было встроено несколько управляющих кодов.

ASCII 28 (0x1C) File Separator - Used to indicate separation between files on a data input stream.
ASCII 29 (0x1D) Group Separator - Used to indicate separation between tables on a data input stream (called groups back then).
ASCII 30 (0x1E) Record Separator - Used to indicate separation between records within a table (within a group).  These roughly map to a tuple in modern nomenclature.
ASCII 31 (0x1F) Unit Separator - Used to indicate separation between units within a record.  The roughly map to fields in modern nomenclature.

Разделитель единиц находится в ASCII, и есть поддержка Юникода для его отображения (обычно это «мы» в одном и том же глифе), но многие шрифты не отображают его.

Если вы хотите отобразить его, я бы порекомендовал отобразить его в приложении после того, как он был разобран в поля.

14 голосов
/ 01 сентября 2010

При использовании разных языков этот символ: ¬

оказался лучшим. Однако я все еще тестирую.

13 голосов
/ 29 января 2009

Как насчет того, чтобы использовать формат в стиле CSV? Символы можно экранировать в стандартном формате CSV, и уже написано много парсеров.

12 голосов
/ 30 января 2009

Вы сказали «печатный», но это могут быть такие символы, как табуляция (0x09) или подача формы (0x0c). Я почти всегда выбираю вкладки, а не запятые для файлов с разделителями, так как запятые иногда могут появляться в тексте.

(Интересно, что таблица ascii содержит символы GS (0x1D), RS (0x1E) и US (0x1F) для разделителей групп, записей и единиц, какими бы они ни были / были.)

Если под «печатным» вы подразумеваете символ, который пользователь может распознать и легко набрать, я бы выбрал трубу | сначала символ, с несколькими другими странными символами (@ или ~ или ^ или \, или backtick, которые я не могу ввести здесь) в качестве возможности. Эти символы +=!$%&*()-'":;<>,.?/ кажутся более вероятными при вводе пользователем. Что касается подчеркивания _ и хеша # и скобок {}[] Я не знаю.

9 голосов
/ 29 января 2009

Можете ли вы использовать символ трубы? Обычно это следующий наиболее распространенный разделитель после строк с запятой или табуляцией. Маловероятно, что большая часть текста будет содержать канал, и ord ('|') возвращает мне 124, так что, похоже, он соответствует вашим требованиям.

7 голосов
/ 13 августа 2011

Для быстрого побега я использую такие вещи: скажем, вы хотите объединить str1, str2 и str3 что я делаю это:

delimitedStr=str1.Replace("@","@a").Replace("|","@p")+"|"+str2.Replace("@","@a").Replace("|","@p")+"|"+str3.Replace("@","@a").Replace("|","@p");

затем, чтобы восстановить исходное использование:

splitStr=delimitedStr.Split("|".ToCharArray());
str1=splitStr[0].Replace("@p","|").Replace("@a","@");
str2=splitStr[1].Replace("@p","|").Replace("@a","@");
str3=splitStr[2].Replace("@p","|").Replace("@a","@");

примечание: важен порядок замены

его небьющийся и простой в реализации

2 голосов
/ 11 февраля 2009

Это может быть хорошо или плохо (как правило, плохо) в зависимости от ситуации и языка, но имейте в виду, что вы всегда можете закодировать Base64 целиком. Тогда вам не нужно беспокоиться о экранировании и удалении различных шаблонов с каждой стороны, и вы можете просто разделять и разбивать строки на основе символа, который не используется в вашей кодировке Base64.

Мне пришлось прибегнуть к этому решению, когда я столкнулся с помещением документов XML в свойства / узлы XML. В свойствах вообще не может быть блоков CDATA, и узлы вышли из строя, поскольку CDATA, очевидно, не может содержать внутри себя дополнительные блоки CDATA, не нарушая структуру.

CSV, вероятно, является лучшей идеей для большинства ситуаций.

2 голосов
/ 30 января 2009

Мы используем ascii 0x7f, который является псевдопечатаемым и вряд ли когда-либо появится в регулярном использовании.

...