Не зацикливайтесь на Split (), который является решением!Это просто разобрать без него.Ответы на регулярные выражения, вероятно, тоже в порядке, но я думаю, что с точки зрения необработанной эффективности создание "парсера" могло бы сработать.
IEnumerable<string> Parse(string input)
{
var results = new List<string>();
int startIndex = 0;
int currentIndex = 0;
while (currentIndex < input.Length)
{
var currentChar = input[currentIndex];
if (currentChar == '{')
{
startIndex = currentIndex + 1;
}
else if (currentChar == '}')
{
int endIndex = currentIndex - 1;
int length = endIndex - startIndex + 1;
results.Add(input.Substring(startIndex, length));
}
currentIndex++;
}
return results;
}
Так что это не коротко.Он повторяется один раз и выполняет только одно распределение на «результат».С небольшими изменениями я мог бы сделать C # 8-версию с индексными типами, которая сокращает распределение?Это, вероятно, достаточно хорошо.
Вы могли бы потратить целый день на то, чтобы понять, как понимать регулярное выражение, но это так просто:
- Сканирование каждого символа.
- Если вы найдете
{
, обратите внимание, что следующий символ является началом результата. - Если вы найдете
}
, рассмотрите все от последнего отмеченного «начала» до индекса перед этим символом.как "результат".
Это не приведет к несовпадению скобок и может вызвать исключения для строк, таких как "}} {".Вы не просили обработать эти случаи, но не слишком сложно улучшить эту логику, чтобы поймать ее и кричать об этом или восстанавливаться.
Например, вы можете сбросить startIndex
на что-то вроде -1, когда}
найдено.Отсюда вы можете сделать вывод, если найдете {
когда startIndex! = -1 вы нашли "{{".И вы можете сделать вывод, если вы найдете }
когда startIndex == -1, вы нашли "}}".И если вы выйдете из цикла с startIndex <-1, это открытие <code>{ без закрытия }
.это оставляет строку "} whoops" как непокрытый случай, но ее можно обработать, инициализируя startIndex
, скажем, -2 и проверяя это специально.Сделайте это с регулярным выражением, и у вас будет болеть голова.
Основная причина, по которой я предлагаю это, - вы сказали "эффективно".Решение IcePickle хорошо, но Split()
делает одно распределение для каждого токена, затем вы выполняете распределение для каждого вызова TrimX()
.Это не "эффективно".Это "n + 2 распределения".