Я бы предложил использовать регулярное выражение для анализа строк. Вот некоторые рабочий код:
var text = @"Command sent from hmi(0).ctq[0] to calh(1).ctq[0] v:1,
Command sent from ptov(21) to bo(1).ctq[10] v:0,
Command answer from bo(1) to ptov(21) code:15 - complete,
Event ptof(1).sgn[7] v:0 s:0601,
Command sent from ptuf(1) to bo(1).ctq[5] v:0,";
var lines = text.Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
);
var regex = new Regex(@"^(?:(?<C0>Event) (?<C1>\S+) (?<C2>\S+) (?<C3>\S+)|(?<C0>Command) (?:answer|sent) from (?<C1>\S+) to (?<C2>\S+) (?<C3>.+)),$");
var result = lines
.Select(line => regex.Match(line))
.Select(
match => new {
C0 = match.Groups["C0"].Value,
C1 = match.Groups["C1"].Value,
C2 = match.Groups["C2"].Value,
C3 = match.Groups["C3"].Value
}
);
Результат:
C0 | C1 | C2 | C3 |
--------+----------------+----------------+--------------------+
Command | hmi(0).ctq[0] | calh(1).ctq[0] | v:1 |
Command | ptov(21) | bo(1).ctq[10] | v:0 |
Command | bo(1) | ptov(21) | code:15 - complete |
Event | ptof(1).sgn[7] | v:0 | s:0601 |
Command | ptuf(1) | bo(1).ctq[5] | v:0 |
Вы не указали, как разобрать Command answer from
линии, так что я взял на себя смелость, чтобы сделать какое-то решение об этом сам. Кроме того, я только что создал запрос LINQ, который будет анализировать строки в последовательности анонимных объектов. См. Ниже, где я показываю, как заполнять результаты в DataTable
(немного более шумный код).
Вот некоторые основные моменты регулярного выражения:
(?<C0>Event)
является именованной группой, которая соответствует Event
. Имя равно C0
(нулевой столбец), а совпадающее значение группы доступно в объекте Match
после того, как было выполнено совпадение.
(?:answer|sent)
- группа, не связанная с захватом, которая будет соответствовать либо answer
, либо sent
, но то, что она соответствует, не фиксируется. Основная часть регулярного выражения также составлена из группы, не связанной с захватом, которая будет соответствовать линии Command
или линии Event
.
\S+
соответствует одному или нескольким символам без пробелов.
Начиная регулярное выражение с ^
и заканчивая его $
, обеспечивается соответствие всей строки.
Чтобы поместить результаты в DataTable
вы можете оставить анонимный тип, а вместо этого использовать этот код (заменяющего из var result = lines
строки кода):
var matches = lines.Select(line => regex.Match(line));
var dataTable = new DataTable();
foreach (var columnName in new[] { "A", "B", "C", "D" })
dataTable.Columns.Add(columnName);
foreach (var match in matches)
dataTable.Rows.Add(
match.Groups.Cast<Group>().Skip(1).Select(group => group.Value).ToArray()
);
Единственная сложная часть является Skip(1)
где первая группа в матче пропускается. Первая группа - это весь матч.Пропуская это, я знаю, что четыре оставшиеся группы - от C0 до C3, а затем значения используются для создания массива со значениями столбцов для строки.
Поскольку я не использую имена групп, их можно фактически удалить из обычного выражения. Например. (?<C1>\S+)
может быть заменен на (\S+)
и т. Д.
Я только что выбрал A, B, C и D как случайные имена для столбцов.
Звучит как задание для [RegularExpressions] (http://msdn.microsoft.com/library/system.text.regularexpressions.regex.aspx). – Corak
'@"^(? Command) \ s. *? From \ s (? . *?) \ Sto \ s (? [^ \ s] +) \ s (? . *) $ "' что вы получите большую часть пути, но загляните в «Регулярное» и «Матч». –
Можете ли вы немного объяснить это регулярное выражение, которое вы написали? Я уже использовал перед Regex, но я не продвинутый, и мне все еще сложно. – user2592968