CSV редактор
arData = sLine.Split(new char[] {','}, StringSplitOptions.None);
и всё вроде бы хорошо, но проблема в том что тип данных может быть и строка, заключённая в двойные кавычки и в этой строке может быть запятая, и получается что сепаратор найдя запятую разделяют эту строку данных, что и не хотелось бы, может кто подсказать как обходить данные в двойных кавычках, для полного понимания даю пример квеста из одной игры
10,Квестовый свиток,"Рога Вилорогого оленя широко используются для изготовления различных предметов. Этот олень водится в окрестностях Ронделла.\n\nПринесите 5 Рогов оленя, и мы хорошо заплатим вам за них.\n\n- Гильдия ремесленников Бильдерберга."
Программа должна различать 3 переменные, 10 - квестовый свиток - остальной текст в двойных кавычках, на данный момент она распознаёт как 4, найдя запятую внутри третьего данного после слов Рогов оленя,
Можно поступить по другому: сначала выделить часть строки до первых кавычек, а затем расщепить полученную строку:
string s = sLine.Substring(0, sLine.IndexOf('\"') - 1);
string[] arData = s.Split(',');
Можно поступить по другому: сначала выделить часть строки до первых кавычек, а затем расщепить полученную строку:
string s = sLine.Substring(0, sLine.IndexOf('\"') - 1);
string[] arData = s.Split(',');
Количество подстрок постоянно меняется, имеется разный набор файлов с разным количеством данных и строк
А с расщеплением тоже получается не вариант, файлов много и количество возвращаемых подстрок тоже немеренно и они уже изначально не имеют экранирования, была у меня тоже идея сделать такой разделитель к примеру ; который не встречается нигде и получается в DataGriw создаётся нужное количество колонок с правильными данными
Но хитрые корейцы придумали же как-то =_))
Не совсем понял способ применения регулярного выражения, msdn ничего не дал по методу match. Вот по сути код чтения строк
arData = sLine.Split(new string[] { Delimiter }, StringSplitOptions.None);
drData = dtData.NewRow();
for (int i = 0; i < dtData.Columns.Count; i++)
{
if (i < arData.Length)
{
drData = arData;
}
}
iRows++;
if (MaxRows > 0 && iRows > MaxRows)
{ break; }
dtData.Rows.Add(drData);
sLine = CleanString(oTR.ReadLine());
if (sLine == null) { break; }
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication30 {
class Program {
private static readonly Regex csv_pattern = new Regex("((\"(?<entry>((\"\")|,|;|[^,;])+)\")|(?<entry>[^,;]*?(\"(,|;)?\"[^,;]*?)*?)|(?<entry>[^,;]*?))(,|;|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
static void Main(string[] args) {
string[] lines = new string[] {
"aaa,bbb,cc,d,e",
"\"3123,123\",sdf",
"\",\""
};
foreach (string line in lines) {
foreach (Match m in csv_pattern.Matches(line)) {
Group g = m.Groups["entry"];
if (null != g && g.Success) {
string value = g.Value
.Replace("\"\"", "\"")
.Replace("\",\"", ",")
.Replace("\";\"", ";")
.Replace("\\n", Environment.NewLine);
Console.Write(value);
Console.Write(" ### ");
}
}
Console.WriteLine();
}
Console.ReadKey(true);
}
}
}
Вроде работает по спецификации CSV, только добавляет дополнительный пустой столбец в конце, лень пилить регулярку.
CSV строка имеет вид:
10,Квестовый свиток,Хороший материал,Соберите 5 Рогов оленя и отнесите их агенту.,"Рога Вилорогого * Гильдия ремесленников Бильдерберга.",0,0,0,0,0,"Хм, как быстро вы вернулись…",0,0
Ну создаётся поток чтения и сам код после него
StringBuilder sBuilder = new StringBuilder();
int id = 1;
foreach (string subStr in Regex.Split(text, "\"|,\""))
{
sBuilder.AppendFormat("{0}: {1}\n", id++, subStr);
}
Результатом получается
1:10,Квестовый свиток,Хороший материал,Соберите 5 Рогов оленя и отнесите их агенту.
2:Рога Вилорогого * Гильдия ремесленников Бильдерберга.
3:,0,0,0,0,0
4:Хм, как быстро вы вернулись…
5:,0,0
Проблема заключается в регулярке, не могу никак построить чтобы считывал запятые вне двойных кавычек тоже
string input = "10,Квестовый свиток,Хороший материал,Соберите 5 Рогов оленя и отнесите их агенту.,\"Рога Вилорогого * Гильдия ремесленников Бильдерберга.\",0,0,0,0,0,\"Хм, как быстро вы вернулись…\",0,0";
string pattern = string.Format("{0}(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))", separator);
string [] result = Regex.Split(input, pattern);
foreach (string str in result)
{
Console.WriteLine(str);
}