Учитывая, что каждое слово перед двоеточием всегда имеет хотя бы одну заглавную букву (пожалуйста, подтвердите), вы могли бы решить это с помощью регулярных выражений (в противном случае вы бы разбили все двоеточия, которые также появляются внутри предложений):
var resultDict = Regex.Split(input, @"(?<= [A-Z][a-zA-Z]+):")
.ToDictionary(a => a[0], a => a[1]);
(?<=...)
- это положительное выражение для обратного просмотра , которое не «съедает» символы, поэтому из вывода удаляется только двоеточие.Протестировано с вашим вводом здесь .
[A-Z][a-zA-Z]+
означает: слово, начинающееся с заглавной буквы.
Обратите внимание, что, как и другие предлагали, "умнее"delimiter обеспечит более простой синтаксический анализ, как и экранирование (например, "::" или ":", когда вам необходимо использовать двоеточия. Хотя не уверен, что это варианты для вас, отсюда и решение с регулярными выражениями выше.
Редактировать
По той или иной причине я продолжал получать ошибки при использовании ToDictionary, так что вот невинтованная версия, по крайней мере, она работает. Извините за более раннюю нерабочую версию. Не то, чтобы регулярное выражение былоизменен, первый не включает ключ, который является обратным к данным.
var splitArray = Regex.Split(input, @"(?<=( |^)[A-Z][a-zA-Z]+):|( )(?=[A-Z][a-zA-Z]+:)")
.Where(a => a.Trim() != "").ToArray();
Dictionary<string, string> resultDict = new Dictionary<string, string>();
for(int i = 0; i < splitArray.Count(); i+=2)
{
resultDict.Add(splitArray[i], splitArray[i+1]);
}
Примечание: регулярное выражение становится немного сложным в этом сценарии. Как предложено в приведенной ниже цепочке, вы можете разделитьэто меньшими шагами. Также обратите внимание, что текущее регулярное выражение создает несколько пустых совпадений, которые я удаляю с помощью выражения Where выше. Цикл for не должен быть нуженЭд, если вам удастся заставить ToDictionary
работать.