У меня есть строка, как показано ниже:
rta_geo5: 09/24/14 15:10:38 - Reset_count = 6
rta_geo5: 09/24/14 15:10:38 - restarting
rta_geo5: 09/24/14 15:10:38 - memory allocation: 3500 lines
Моя цель состоит в том, чтобы разбить эту строку на три столбца, чтобы я мог поместить это в таблицу базы данных:
-------------------------------------------------------------
| COL1 | COL 2 | COL 3 |
-------------------------------------------------------------
| rta_geo5 | 09/24/14 15:10:38 |Reset_count = 6 |
-------------------------------------------------------------
|rta_geo5 | 09/24/14 15:10:38 |restarting |
-------------------------------------------------------------
| rta_geo5 | 09/24/14 15:10:38 |memory allocation: 3500 lines |
-------------------------------------------------------------
Будет ли это возможно с помощью инструкции ниже?
string[] substrings = Regex.Split(input, pattern);
Для этого мне просто нужно правильное регулярное выражение.
Вместо Split вы можете использовать именованные группы в regex
шаблон:
Regex ptrn = new Regex(@"^(?<col1>[^:]+):\s+(?<col2>\d{2}/\d{2}/\d{2} \d{2}:\d{2}:\d{2})\s+-\s+(?<col3>[^\r\n]+?)\s*$",
RegexOptions.ExplicitCapture|RegexOptions.IgnoreCase|RegexOptions.Multiline);
Применение:
string s = @"rta_geo5: 09/24/14 15:10:38 - Reset_count = 6
rta_geo5: 09/24/14 15:10:38 - restarting
rta_geo5: 09/24/14 15:10:38 - memory allocation: 3500 lines";
var matches = ptrn.Matches(s);
Доступ:
matches.OfType<Match>()
.Select(match => new string[]
{
match.Groups["col1"].Value,
match.Groups["col2"].Value,
match.Groups["col3"].Value
})
.ToList().ForEach(a=>System.Console.WriteLine(string.Join("\t|\t",a)));
Или:
foreach (Match match in matches)
{
string col1 = match.Groups["col1"].Value;
string col2 = match.Groups["col2"].Value;
string col3 = match.Groups["col3"].Value;
System.Console.WriteLine(col1 + "\t|\t" + col2 + "\t|\t" + col3);
}
вывод:
rta_geo5 | 09/24/14 15:10:38 | Reset_count = 6
rta_geo5 | 09/24/14 15:10:38 | restarting
rta_geo5 | 09/24/14 15:10:38 | memory allocation: 3500 lines
Я бы не использовал regex (или String.Split) для этого, а цикл, в котором вы разбираете каждую строку. Я бы также использовал специальный класс для сопоставления с таблицей базы данных, чтобы увеличить повторяемость и повторное использование.
Класс (упрощенный):
public class Data
{
public string Token1 { get; set; } // use a meaningful name
public string Token2 { get; set; } // use a meaningful name
public DateTime Date { get; set; } // use a meaningful name
public override string ToString()
{
return string.Format("Token1:[{0}] Date:[{1}] Token2:[{2}]",
Token1,
Date.ToString("MM/dd/yy HH:mm:ss", CultureInfo.InvariantCulture),
Token2);
}
}
Ваша строка образца:
string data = @"rta_geo5: 09/24/14 15:10:38 - Reset_count = 6
rta_geo5: 09/24/14 15:10:38 - restarting
rta_geo5: 09/24/14 15:10:38 - memory allocation: 3500 lines";
Теперь вы можете использовать этот цикл, используя простые строковые методы для синтаксического анализа текста в List<Data>
:
string[] lines = data.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
List<Data> allData = new List<Data>();
foreach (string line in lines)
{
string token1 = null, token2 = null;
DateTime dt;
int firstColonIndex = line.IndexOf(": ");
if (firstColonIndex >= 0)
{
token1 = line.Remove(firstColonIndex);
firstColonIndex += 2; // start next search after first token to find DateTime
int indexOfMinus = line.IndexOf(" - ", firstColonIndex);
if (indexOfMinus >= 0)
{
string datePart = line.Substring(firstColonIndex, indexOfMinus - firstColonIndex);
if (DateTime.TryParseExact(datePart, "MM/dd/yy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
{
indexOfMinus += 3; // start next search after DateTime to get last token
token2 = line.Substring(indexOfMinus);
Data d = new Data { Token1 = token1, Token2 = token2, Date = dt };
allData.Add(d);
}
}
}
}
Контрольная работа:
foreach (Data d in allData)
Console.WriteLine(d.ToString());
Token1:[rta_geo5] Date:[09/24/14 15:10:38] Token2:[Reset_count = 6]
Token1:[rta_geo5] Date:[09/24/14 15:10:38] Token2:[restarting]
Token1:[rta_geo5] Date:[09/24/14 15:10:38] Token2:[memory allocation: 3500 lines]
Этот подход является более подробным, но более эффективным/поддерживаемым, чем другие. Он также позволяет регистрировать аномалии или использовать другие методы для его анализа.
string data = @ ...
)? Я снова протестировал код, и он правильно показывает результат выше. Что содержат lines
string []? Вы копировали и вставляли переносы строк?
разделите на это:
(?:(?<=geo5):\s|(?<=\d{2}:\d{2}:\d{2})\s-\s)
демо здесь:
Ну, подумал об этом, не уверен, что это 100%, но попробуйте:
(rta_geo5): (.*?) - (.*)
Если нужно, разделите его на 3 группы. Однако он предполагает, что ведущий идентификатор всегда (rta_geo5)
.
[edit] -I обратите внимание, что один из ответов ссылается на онлайн-службу regex, поэтому вы можете попробовать использовать мое регулярное выражение внутри: http://regex101.com/r/xF7iD7/1 (извините, у вас нет учетной записи но -but создаст прямо сейчас) -also, касается блока rta_geo5, вы, конечно, могли бы стать полностью родным с
(.*): (.*) - (.*)
посмотреть, как это работает в любом случае
rta_geo5:
иallocation:
? Какие строгие правила вы хотите использовать для раскола?