Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

CSV редактор

54K
30 ноября 2009 года
badwolf
5 / / 30.11.2009
Проблема заключается в следующем, файл CSV с разделяющими данными через запятую
arData = sLine.Split(new char[] {','}, StringSplitOptions.None);
и всё вроде бы хорошо, но проблема в том что тип данных может быть и строка, заключённая в двойные кавычки и в этой строке может быть запятая, и получается что сепаратор найдя запятую разделяют эту строку данных, что и не хотелось бы, может кто подсказать как обходить данные в двойных кавычках, для полного понимания даю пример квеста из одной игры

10,Квестовый свиток,"Рога Вилорогого оленя широко используются для изготовления различных предметов. Этот олень водится в окрестностях Ронделла.\n\nПринесите 5 Рогов оленя, и мы хорошо заплатим вам за них.\n\n- Гильдия ремесленников Бильдерберга."

Программа должна различать 3 переменные, 10 - квестовый свиток - остальной текст в двойных кавычках, на данный момент она распознаёт как 4, найдя запятую внутри третьего данного после слов Рогов оленя,
297
30 ноября 2009 года
koodeer
1.2K / / 02.05.2009
Во-первых, можно просто указать в методе Split количество возвращаемых подстрок:
 
Код:
arData = sLine.Split(new char[] {','}, [highlight]3[/highlight], StringSplitOptions.None);
Но это применимо только в том случае, если заранее известно количество подстрок.

Можно поступить по другому: сначала выделить часть строки до первых кавычек, а затем расщепить полученную строку:
 
Код:
string sLine = "10,Квестовый свиток,\"Рога Вилорогого оленя широко используются для изготовления различных предметов. Этот олень водится в окрестностях Ронделла.\n\nПринесите 5 Рогов оленя, и мы хорошо заплатим вам за них.\n\n- Гильдия ремесленников Бильдерберга.\"";
string s = sLine.Substring(0, sLine.IndexOf('\"') - 1);
string[] arData = s.Split(',');
5
30 ноября 2009 года
hardcase
4.5K / / 09.08.2005
Следующая регулярка в каждое сопоставление строки (Match) будет помещать в группу "content". "Понимает" эскейп последовательности \", \, и ,
 
Код:
(?<content>"(\\"|\\,|,|.)*?")|(?<content>.*?)(,|$)
Единственная проблема: в конце добавляет сопоставление с пустой строкой (срабатывает правило .*?$).
54K
30 ноября 2009 года
badwolf
5 / / 30.11.2009
Цитата: koodeer
Во-первых, можно просто указать в методе Split количество возвращаемых подстрок:
 
Код:
arData = sLine.Split(new char[] {','}, [highlight]3[/highlight], StringSplitOptions.None);
Но это применимо только в том случае, если заранее известно количество подстрок.

Можно поступить по другому: сначала выделить часть строки до первых кавычек, а затем расщепить полученную строку:
 
Код:
string sLine = "10,Квестовый свиток,\"Рога Вилорогого оленя широко используются для изготовления различных предметов. Этот олень водится в окрестностях Ронделла.\n\nПринесите 5 Рогов оленя, и мы хорошо заплатим вам за них.\n\n- Гильдия ремесленников Бильдерберга.\"";
string s = sLine.Substring(0, sLine.IndexOf('\"') - 1);
string[] arData = s.Split(',');


Количество подстрок постоянно меняется, имеется разный набор файлов с разным количеством данных и строк
А с расщеплением тоже получается не вариант, файлов много и количество возвращаемых подстрок тоже немеренно и они уже изначально не имеют экранирования, была у меня тоже идея сделать такой разделитель к примеру ; который не встречается нигде и получается в DataGriw создаётся нужное количество колонок с правильными данными
Но хитрые корейцы придумали же как-то =_))

54K
30 ноября 2009 года
badwolf
5 / / 30.11.2009
Цитата: hardcase
Следующая регулярка в каждое сопоставление строки (Match) будет помещать в группу "content". "Понимает" эскейп последовательности \", \, и ,
 
Код:
(?<content>"(\\"|\\,|,|.)*?")|(?<content>.*?)(,|$)
Единственная проблема: в конце добавляет сопоставление с пустой строкой (срабатывает правило .*?$).


Не совсем понял способ применения регулярного выражения, 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; }

5
30 ноября 2009 года
hardcase
4.5K / / 09.08.2005
Код:
using System;
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, только добавляет дополнительный пустой столбец в конце, лень пилить регулярку.
54K
01 декабря 2009 года
badwolf
5 / / 30.11.2009
Хм, покопался тут и что-то вроде нащупал, но не до конца
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

Проблема заключается в регулярке, не могу никак построить чтобы считывал запятые вне двойных кавычек тоже
54K
01 декабря 2009 года
badwolf
5 / / 30.11.2009
Нашёл своё решение, выкладываю ибо может кому-то поможет
Код:
string separator = ",";
            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);
            }
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог