Наименее используемый символ-разделитель в обычном тексте
по причинам кодирования, которые ужаснут вас (я слишком смущен, чтобы сказать), мне нужно сохранить несколько текстовых элементов в одной строке.
Я разделю их с помощью символа.
какой символ лучше всего использовать для этого, т. е. какой символ наименее вероятно появится в тексте? Должен быть доступен для печати и, вероятно, менее 128 в ASCII, чтобы избежать проблем с языковым стандартом.
16 ответов
предполагая, по какой-то неловкой причине вы не можете использовать CSV, я бы сказал, идти с данными. Возьмите несколько примеров данных и выполните простой подсчет символов для каждого значения 0-127. Выберите один из тех, которые не происходят. Если есть слишком большой выбор, получите больший набор данных. Это не займет много времени, чтобы написать, и вы получите ответ лучше для вас.
ответ будет разным для разных проблемных областей, поэтому | (pipe) распространен в сценариях оболочки, ^ распространен в математических формулах и то же самое вероятно, это верно для большинства других персонажей.
Я лично думаю, что я бы пошел на | (pipe), если бы у меня был выбор, но идти с реальными данными безопаснее.
и что бы вы ни делали, убедитесь, что вы разработали схему побега!
Я бы выбрал" unit separator "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.
Unit Separator находится в ASCII, и есть поддержка Unicode для его отображения (обычно "us" в том же глифе), но многие шрифты не отображают его.
Если вы должны отобразить его, я бы рекомендовал отобразить его в приложении, после того, как он был разбит на поля.
Как насчет использования формата стиля CSV? Символы могут быть экранированы в стандартном формате CSV, и уже написано много синтаксических анализаторов.
Вы сказали "printable", но это может включать символы, такие как вкладка (0x09) или канал формы (0x0c). Я почти всегда выбираю вкладки, а не запятые для файлов с разделителями, поскольку запятые иногда могут появляться в тексте.
(достаточно интересно таблица ascii имеет символы GS (0x1D), RS (0x1E) и US (0x1F) для групповых, записывающих и единичных сепараторов, какими бы они ни были/были.)
если под "printable" вы подразумеваете символ, который пользователь может распознать и легко введите, я бы пошел на трубу | символ сначала, с несколькими другими странными символами (@
или ~
или ^
или \
, или backtick, который я не могу ввести здесь) как возможность. Эти персонажи +=!$%&*()-'":;<>,.?/
похоже, что они будут более вероятны при вводе пользователем. Что касается подчеркивания _
и хэш #
а скобки {}[]
Я не знаю.
вы можете использовать символ? Обычно это следующий наиболее распространенный разделитель после строк с разделителями-запятыми или вкладками. Маловероятно, что большинство текстов будет содержать трубку, а ord('|') возвращает 124 для меня, так что это, похоже, соответствует вашим требованиям.
для быстрого побега я использую такие вещи: скажем, вы хотите конкатинировать str1, str2 и str3 вот что я делаю:--3-->
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","@");
Примечание: порядок замены важно
свой ломкий и легкий для того чтобы снабдить
мы используем ascii 0x7f, который псевдо-печатается и вряд ли когда-либо появляется в обычном использовании.
Это может быть хорошо или плохо (обычно плохо) в зависимости от ситуации и языка, но имейте в виду, что вы всегда можете Base64 кодировать все это. Затем вам не нужно беспокоиться о том, чтобы избежать и отменить различные шаблоны с каждой стороны, и вы можете просто отделить и разделить строки на основе символа, который не используется в вашей кодировке Base64.
Мне пришлось прибегнуть к этому решению, столкнувшись с помещением XML-документов в свойства/узлы XML. Свойства не могут иметь Блоки CDATA в них вообще, и узлы, экранированные как CDATA, очевидно, не могут иметь дальнейших блоков CDATA внутри, не нарушая структуру.
CSV, вероятно, лучшая идея для большинства ситуаций.
Ну, это будет зависеть от характера вашего текста в некоторой степени, но вертикальная полоса 0x7C не очень часто появляется в тексте.
Я не думаю, что когда-либо видел амперсанд, за которым следует запятая в естественном тексте, но вы можете сначала проверить файл, чтобы увидеть, содержит ли он разделитель, и если да, используйте альтернативу. Если вы хотите всегда знать, что используемый вами разделитель не вызовет конфликта, выполните цикл проверки файла на наличие нужного разделителя, а если он существует, то удвоите строку, пока файл больше не будет иметь совпадения. Не имеет значения, есть ли похожие строки, потому что ваша программа будет ищите только точные совпадения разделителей.
вам, вероятно, придется выбрать что-то и игнорировать другие его использования.
+
может быть хорошим кандидатом.
и труба и каретка очевидные выборы. Я бы отметил, что если пользователи должны ввести весь ответ, курсор легче найти на любой клавиатуре, чем на трубе.
Я не уверен, что вы должны использовать ASCII, но если вы можете кодировать его в UTF-8, вы можете найти действительно неясный символ, такой как:╡
(U+2561) - который я часто использую в своих программах.
вы также можете посмотреть сериализацию объектов и просто создать новые поля для всех элементов, которые вам могут понадобиться.