Вы можете создать метод расширения LINQ, чтобы получить IEnumerable<string>
деталей:
public static class Extensions
{
public static IEnumerable<string> SplitNthParts(this string source, int partSize)
{
if (string.IsNullOrEmpty(source))
{
throw new ArgumentException("String cannot be null or empty.", nameof(source));
}
if (partSize < 1)
{
throw new ArgumentException("Part size has to be greater than zero.", nameof(partSize));
}
return Enumerable
.Range(0, (source.Length + partSize - 1) / partSize)
.Select(pos => source
.Substring(pos * partSize,
Math.Min(partSize, source.Length - pos * partSize)));
}
}
Использование:
var strings = new string[] {
"00122345",
"001223453"
};
foreach (var str in strings)
{
Console.WriteLine(string.Join(":", str.SplitNthParts(2)));
}
// 00:12:23:45
// 00:12:23:45:3
Объяснение:
- Используйте
Enumerable.Range
, чтобы получить количество позиций для среза строки. В этом случае это length of the string + chunk size - 1
, так как нам нужно получить достаточно большой диапазон, чтобы также соответствовать оставшимся размерам куска. Enumerable.Select
каждой позиции нарезки и получите startIndex
, используя String.Substring
, используя позицию, умноженную на 2, чтобы перемещаться вниз по строке каждые 2 символа. Вам нужно будет использовать Math.Min
для вычисления наименьшего размера оставшегося размера, если в строке недостаточно символов для размещения другого фрагмента. Вы можете вычислить это как length of the string - current position * chunk size
. String.Join
конечный результат с ":"
.
Вы также можете заменить запрос LINQ на yield
здесь для увеличения производительности для больших строк, так как все подстроки не будут сохранены в памяти сразу:
for (var pos = 0; pos < source.Length; pos += partSize)
{
yield return source.Substring(pos, Math.Min(partSize, source.Length - pos));
}