Вы можете использовать MessageFormat
Wellcome: {0} {1}
В коде Java:
String text =MessageFormat(R.string.customer_address).format("Name","Family");
Уровень API 1:
https: / /developer.android.com/reference/java/text/MessageFormat.html
| будет следующим в моем списке и часто используется в качестве альтернативы CSV. google "pipe delimited", и вы найдете много примеров.
string[] items = new string[] {"Uno","Dos","Tres"};
string toEncrypt = String.Join("|", items);
items = toEncrypt.Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
foreach(string s in items)
Console.WriteLine(s);
И так как все любят критиковать кодировку и не предоставлять код, вот один из способов закодировать текст, чтобы ваш | delim не будет сталкиваться.
string[] items = new string[] {"Uno","Dos","Tres"};
for (int i = 0; i < items.Length; i++)
items[i] = Convert.ToBase64String(Encoding.UTF8.GetBytes(items[i]));
string toEncrypt = String.Join("|", items);
items = toEncrypt.Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in items)
Console.WriteLine(Encoding.UTF8.GetString(Convert.FromBase64String(s)));
Я также поддерживаю выбор TAB (\ t) и в некоторой степени расширяю символ PIPE (|).
Но в моем опыте наиболее часто используется точка с запятой (;) вместе с полями в кавычках и экранированными символами \ и \ ", что просто идеально. Просто нужен анализатор, сохраняющий состояние. Фактический разделительный символ становится неважным.
Если вы не используете escape, имеет смысл посчитать «поля» в строке и сравнить их с ожидаемыми результатами. Поскольку большинство приложений такого типа файлов используют какое-то фиксированное количество полей, вы можете обнаружить ошибки в вход и получить это все хорошо, если это не срабатывает.
Я предпочитаю использовать комбинацию символов, которая вряд ли будет введена обычным человеком в качестве моего разделителя, когда это возможно. Например, я использовал ") ^ & amp; ^ (" и настроил его как const "cDelimiter" в своем коде, а затем соединил все мои поля с этим. Используя небольшую уникальную строку, я значительно уменьшил вероятность Уловка пользователя, случайно входящего в мой разделитель. Вероятная уловка пользователя, вводящего | или ~, по общему признанию маловероятна, но это не означает, что этого не произойдет.
Newline? (т.е. используйте многострочное текстовое поле)
Почему бы вам не обернуть каждый вход в кавычки?
Таким образом, вы получите следующее:
"Aaron","Johnson","25","I like cats, and dogs"
Не забудьте экранировать кавычки на входе ...
Я полагаю, в конце концов, каждый персонаж будет использоваться кем-то. Пользователи всегда находят способ сломать наш HL7-парсер.
Вместо одного символа, возможно, попробуйте строку, которая будет достаточно случайной, чтобы никто ее не использовал. Что-то вроде "#! @! #".
Лучшее решение - придерживаться запятых и вводить поддержку экранирования символов. Какой бы персонаж вы ни выбрали, в конечном итоге его нужно будет ввести, так что вы также можете оказать поддержку.
Вспомните обратные слэзы + двойные кавычки внутри строк в двойных кавычках.
Не выбирайте такой символ, как обратный удар, потому что некоторые пользователи могут не знать, как его набрать ...
Если бы Вы хотите использовать действительно уникальный разделитель, я рекомендовал бы ╡
или уникальная строка \u2561
.
Используйте вкладку (или, может быть, \ n) - которая при вводе пользователем приведет к выходу из текстового поля.
Символ трубы (|), возможно? Если ваша пользовательская база удаленно IT-стеснительна, то этот подход (с просьбой разграничить текст) может оказаться не лучшим; Вы можете попробовать что-то еще, например, предоставить некоторые средства динамического добавления текстового поля на лету, которое принимает другую строку, и т. д.
Если вы предоставите немного больше информации о том, что вы делаете, и для кого, это может быть кто-то может предложить альтернативный подход.
Марк Брекетт имеет правильный ответ. Я только добавлю, что само количество ответов на этот простой вопрос должно вас вообще не использовать с разделителями. Пусть это будет «словом к мудрым».
Как уже отмечалось, любой выбранный вами персонаж может появиться на входе, поэтому вам придется обрабатывать экранирование. XML может быть хорошим форматом для сериализации, так как я считаю, что .NET имеет хорошую поддержку создания и удаления XML. Это, вероятно, будет гораздо более надежным, чем попытка реализовать экранирование вашего собственного персонажа, а также будет более расширяемым в будущем.
I have seen unusal characters used as delimiters, even unusal character combinarions like -|::|-
, but eventhough they are more unlikely to occur, they still can.
You have basically two options if you want to make it water tight:
1: Use a character that is impossible to type, like the '\0' character:
Join:
string combined = string.Join("\0", inputArray);
Split:
string[] result = combined.Split('\0');
2: Escape the string and use an escaped character as delimiter, like url encoding the values and use & as delimiter:
Join:
string combined = string.Join("&", inputArray.Select<string,string>(System.Web.HttpUtility.UrlEncode).ToArray());
Split:
string[] result = combined.Split('&').Select<string,string>(System.Web.HttpUtility.UrlDecode).ToArray();
Не думаю, что я добровольно разделил коллекцию строк с тех пор, как перестал использовать C. Нет необходимости в этом на «современном» языке, и - хотя и тривиально - количество крайних случаев достаточно, чтобы раздражать вас до смерти.
Сохраните их в List
В C # это меньше LOC и требует меньше времени для записи, чем этот ответ. Нет никакого оправдания тому, чтобы накатить собственное решение.
Определите символ, который не используется, и затем используйте его. Ваша последняя объединенная строка может начинаться с символа, который должен быть с этой точки и использоваться в качестве разделителя. Пример:
ваши пользователи вводят "штаны" ",;,;,;,;;" и "| ~~ |" Вы перебираете набор символов, пока не найдете тот, который не используется. Может быть, скажем, "$" Ваша последняя объединенная строка - это "$ants $,;,;,;,;,; $ | ~~ |" Начальный символ сообщает вашей программе, какой символ должен использоваться в качестве разделителя. Таким образом, нет запрещенных символов, точка.
Из того, что вы говорите, я предполагаю, что пользователь вводит данные в отдельные поля, а затем вы их комбинируете. Таким образом, пользователю никогда не нужно знать или заботиться о том, что такое разделитель.
Не просто пытайтесь выбрать символ, который «никто никогда не использует», потому что либо случайно, либо чтобы попытаться взломать ваш код, какой-то пользователь в конце концов, используйте его.
Итак, я бы либо:
Вставил обратную косую черту, чтобы избежать запятых и обратной косой черты в пользовательском вводе, затем объединял строки с запятыми. Для разделения вы разделяете неэкранированные запятые (что является заданием для конечного автомата), а затем удаляете все компоненты.
Используйте готовые средства сериализации списка строк. Доступность зависит от вашей среды, я недостаточно хорошо знаю C # / .NET, чтобы посоветовать. В Java вы можете просто сериализовать вектор или что-то еще.
Разделите данные управляющим символом, таким как ASCII-BEL или ASCII-VT (или ASCII-NUL, если ваши строки никогда не обрабатываются как нуль-завершенные), и отклоните ввод пользователя, который содержит этот символ.
Первый вариант хорошо, если пользователю нужно разрешить вводить любые значения символов, которые ему нравятся. Второй вариант хорош, если вы не заботитесь о раздувании данных значительно. Третий вариант хорош, если вы не против отклонить пользователей smart-alec (или пользователей с необычными требованиями), которые пытаются вставить забавные данные.
не заботиться о раздувании данных значительно. Третий вариант хорош, если вы не против отклонить пользователей smart-alec (или пользователей с необычными требованиями), которые пытаются вставить забавные данные. не заботиться о раздувании данных значительно. Третий вариант хорош, если вы не против отклонить пользователей smart-alec (или пользователей с необычными требованиями), которые пытаются вставить забавные данные.Любой из нестандартных символов pipe |, backtick `, tilde ~, bang! Или точка с запятой; вероятно, будет работать. Однако, если вы пойдете по этому пути, вы действительно откажетесь от юзабилити. Попросить у них запятые с обратной косой чертой или что-то в этом роде, умоляя их пропустить один.
Если CSV невозможен, вам следует подумать об изменении вашего пользовательского интерфейса. (Черт, вы все равно должны держаться подальше от CSV для пользовательского ввода!) Вы говорите текстовое поле, поэтому я предполагаю, что вы находитесь в Интернете или в какой-то форме выигрышных форм или WPF (определенно не консоль). Все это дает вам лучший контроль над пользовательским интерфейсом, чем одно текстовое поле, и заставляет пользователей соответствовать вашему сложному дизайну пользовательского интерфейса.
Более подробная информация определенно поможет лучше направлять ответы.
Однако, как пример экранирования запятой с обратной косой чертой. , Обратите внимание, что вы не можете избежать обратной косой черты перед запятой с этим. Так что @ "uno, dos, tr \\, es" в конечном итоге будет {"uno", "dos", "tr \ es"}.
string data = @"uno, dos, tr\,es";
string[] items = data.Split(','); // {"uno", " dos", @"tr\", "es"}
List<string> realitems = new List<string>();
for (int i=items.Length-1; i >= 0; i--)
{
string item = items[i];
if (item.Length == 0) { realitems.Insert(0, ""); continue; }
if (realitems.Count == 0) { realitems.Insert(0, item); }
else
{
if (item[item.Length - 1] == '\\') { realitems[0] = item + "," + realitems[0]; }
else { realitems.Insert(0, item); }
}
}
// Should end up with {"uno", " dos", "tr,es"}
Никто не сказал, TAB? Разделение табуляции отлично, но нелегко набирать вкладки в графическом интерфейсе (это приводит к переходу к следующему элементу экрана). Но для файлов, сгенерированных компьютером, TAB идеально подходит, поскольку он действительно никогда не должен появляться в сгенерированном пользователем тексте.
Будет ли пользователь вводить строки с разделителями в текстовые поля или они будут вводить отдельные строки, которые затем будут встроены в строки с разделителями с помощью ваш код?
В первом случае, возможно, лучше переосмыслить свой интерфейс. Например, пользователь может вводить одну строку за раз в текстовое поле и нажимать кнопку «Добавить в список» после каждого.
Во втором случае не имеет значения, какой разделитель вы используете. Выберите любой символ, который вам нравится, просто убедитесь, что вы избегаете других вхождений этого символа.
РЕДАКТИРОВАТЬ
Поскольку в нескольких комментариях к другим ответам запрашивается код, вот метод для создания строки с разделителями-запятыми, используя обратную косую черту как побег персонаж:
public static string CreateDelimitedString(IEnumerable<string> items)
{
StringBuilder sb = new StringBuilder();
foreach (string item in items)
{
sb.Append(item.Replace("\\", "\\\\").Replace(",", "\\,"));
sb.Append(",");
}
return (sb.Length > 0) ? sb.ToString(0, sb.Length - 1) : string.Empty;
}
И здесь ' s метод преобразования этой строки через запятую обратно в коллекцию отдельных строк:
public static IEnumerable<string> GetItemsFromDelimitedString(string s)
{
bool escaped = false;
StringBuilder sb = new StringBuilder();
foreach (char c in s)
{
if ((c == '\\') && !escaped)
{
escaped = true;
}
else if ((c == ',') && !escaped)
{
yield return sb.ToString();
sb.Remove(0, sb.Length);
}
else
{
sb.Append(c);
escaped = false;
}
}
yield return sb.ToString();
}
И вот несколько примеров использования:
string[] test =
{
"no commas or backslashes",
"just one, comma",
@"a comma, and a\ backslash",
@"lots, of\ commas,\ and\, backslashes",
@"even\\ more,, commas\\ and,, backslashes"
};
string delimited = CreateDelimitedString(test);
Console.WriteLine(delimited);
foreach (string item in GetItemsFromDelimitedString(delimited))
{
Console.WriteLine(item);
}