Разбор строк с разделителями?
Я смотрю на синтаксический анализ строки с разделителями, что-то в порядке
а, б, в
Но это очень простой пример, и анализ данных с разделителями может оказаться сложным; например
1, "Ваш простой алгоритм, он не работает", Верно
взорвет вашу naiive string.Split реализацию на биты. Есть ли что-нибудь, что я могу свободно использовать / украсть / скопировать и вставить, что предлагает относительно надежное решение для анализа текста с разделителями? .NET, plox.
Обновление: я решил использовать TextFieldParser , который является частью кучи вкусностей VB.NET, спрятанных в Microsoft.VisualBasic.DLL.
Ответов (9)9
Я использую это для чтения из файла
string filename = @textBox1.Text;
string[] fields;
string[] delimiter = new string[] {"|"};
using (Microsoft.VisualBasic.FileIO.TextFieldParser parser =
new Microsoft.VisualBasic.FileIO.TextFieldParser(filename)) {
parser.Delimiters = delimiter;
parser.HasFieldsEnclosedInQuotes = false;
while (!parser.EndOfData) {
fields = parser.ReadFields();
//Do what you need
}
}
Я уверен, что кто-то здесь может преобразовать это в синтаксический анализ строки, которая находится в памяти.
Я думаю, что в общей структуре необходимо указать между двумя вещами: 1. Какие символы-разделители. 2. При каком условии эти символы не учитываются (например, когда они заключены в кавычки).
Я думаю, что может быть лучше написать собственную логику каждый раз, когда вам нужно делать что-то подобное.
Здесь есть несколько хороших ответов: Разделить строку, игнорируя цитируемые разделы
Возможно, вы захотите перефразировать свой вопрос на что-то более точное (например, какой фрагмент кода или библиотеку я могу использовать для анализа данных CSV в .NET ?).
Я не знаю какой-либо структуры, но работает простой конечный автомат:
- Состояние 1. Прочтите все символы, пока не нажмете "или",
- В случае ": перейти в состояние 2"
- В случае: перейти в состояние 3
- В случае конца файла: перейти в состояние 4
- Состояние 2: прочитайте все символы, пока не нажмете "
- В случае ": перейти в состояние 1"
- В случае конца файла: либо перейти в состояние 4, либо сообщить об ошибке из-за незавершенной строки
- Состояние 3: добавить текущий буфер в выходной массив, переместить курсор вперед за и обратно в состояние 1.
- Состояние 4: это конечное состояние, ничего не делает, кроме возврата выходного массива.
Такие как
var elements = new List<string>();
var current = new StringBuilder();
var p = 0;
while (p < internalLine.Length) {
if (internalLine[p] == '"') {
p++;
while (internalLine[p] != '"') {
current.Append(internalLine[p]);
p++;
}
// Skip past last ',
p += 2;
}
else {
while ((p < internalLine.Length) && (internalLine[p] != ',')) {
current.Append(internalLine[p]);
p++;
}
// Skip past ,
p++;
}
elements.Add(current.ToString());
current.Length = 0;
}
Чтобы сделать бессовестный плагин, я какое-то время работал над библиотекой под названием fotelo (Загрузчик форматированного текста), которую я использую для быстрого анализа больших объемов текста на основе разделителя, позиции или регулярного выражения. Для быстрой строки это перебор, но если вы работаете с журналами или большими объемами, это может быть именно то, что вам нужно. Он работает на основе модели управляющего файла, подобной SQL * Loader (что-то вроде вдохновения).
Здесь можно найти очень полную библиотеку: FileHelpers
Лучше поздно, чем никогда (добавьте к полноте SO):
http://www.codeproject.com/KB/database/CsvReader.aspx
Это одно правило.
ГДж