Возможно, вы сможете использовать класс TextFieldParser
. Он может принимать список длин полей для использования при разборе.
using (var parser = new TextFieldParser(new StringReader(s))){
parser.TextFieldType = FieldType.FixedWidth;
parser.SetFieldWidths(2,1,4 /*etc*/);
while (!parser.EndOfData)
{
var data = parser.ReadFields(); //string[]
}
}
Однако это разделило бы ваши данные только на массив строк. Если все виды были IConvertible
, вы могли бы сделать что-то вроде ...
var types = new[] {typeof(int), typeof(string), typeof(string), typeof(DateTime), /*etc..*/ };
var data = parser.ReadFields();
var firstVal = Convert.ChangeType(data[0], types[0]);
var secondVal = Convert.ChangeType(data[1], types[1]);
// etc..
// or in a loop:
for (var i = 0; i<data.Length;++i){
var valAsString = data[i];
var thisType = types[i];
var value = Convert.ChangeType(valAsString , thisType);
// do something with value
}
Convert.ChangeType
хотя, возвращает object
поэтому тип ваших переменных будет типа object
, а если вы не были бросить их:
var firstVal = (int)Convert.ChangeType(data[0], types[0]);
// because unfortunately this is not valid:
var firstVal = (types[0])Convert.ChangeType(data[0], types[0]);
Вы могли быть в состоянии использовать dynamic
ключевое слово в этом случае, хотя мой опыт работы с ней очень мало, и я не уверен, что делает разницу:
dynamic firstVal = Convert.ChangeType(data[0], types[0]);
Обратите внимание, что существуют штрафы производительности, связанные как с dynamic
ключевого слова, а также TextFieldParser
класса, который был документально не самым производительным (просто посмотреть другие SO сообщения по этому вопросу), по крайней мере, с большим строки/файлы. Конечно, использование TextFieldParser
также может быть излишним для вашего случая, если все, что вы делаете, - это синтаксический анализ одной строки.
Если у вас есть DTO класс/Poco, который представляет эти данные, вы всегда можете передать массив строк, возвращенное ReadFields()
в конструктор на вашем DTO, которые могут заселить данные для вас ... то есть:
class Message {
public DateTime DateTime { get; set; }
public int Protocol { get; set; }
public string Type { get; set; }
public string Measurement {get;set;}
public Message(string[] data) {
Protocol = int.Parse(data[0]);
Type = data[1];
Measurement = data[2];
DateTime = DateTime.Parse(data[3]);
}
}
Используйте регулярное выражение для каждого отдельного раздела. Это будет просто и не путать –
'Regex' с группами захвата, вероятно, так, как я бы это сделал, если честно –
Regex - это правильный инструмент для извлечения и синтаксического анализа строки. Группа Regex отображает MyConfig, кроме типа, и почему вы создаете свой собственный? Тем не менее, я не знаю, как вы используете тип здесь. У вас большой переключатель? Это правда, что Regex трудно читать, но вы можете построить его тщательно со многими комментариями. Разделите его на кусочки, и это не будет путать. – qxg