假设我有一个字符串:

string str = "1111222233334444"; 

我如何把这个字符串分成一定大小的块?

例如,将它分解为4的大小将返回字符串:

"1111"
"2222"
"3333"
"4444"

当前回答

你可以用Jon Skeet的morelinq。像这样使用Batch:

string str = "1111222233334444";
int chunkSize = 4;
var chunks = str.Batch(chunkSize).Select(r => new String(r.ToArray()));

这将返回字符串“1111222233334444”的4个块。如果字符串长度小于或等于chunk大小,Batch将返回string作为IEnumerable<string>的唯一元素

输出:

foreach (var chunk in chunks)
{
    Console.WriteLine(chunk);
}

它会给出:

1111
2222
3333
4444

其他回答

如有必要分割几个不同的长度: 例如,日期和时间的指定格式为stringstrangeStr = "07092016090532";07092016090532(日期:07.09.2016时间:09:05:32)

public static IEnumerable<string> SplitBy(this string str, int[] chunkLength)
    {
        if (String.IsNullOrEmpty(str)) throw new ArgumentException();
        int i = 0;
        for (int j = 0; j < chunkLength.Length; j++)
        {
            if (chunkLength[j] < 1) throw new ArgumentException();
            if (chunkLength[j] + i > str.Length)
            {
                chunkLength[j] = str.Length - i;
            }
            yield return str.Substring(i, chunkLength[j]);
            i += chunkLength[j];
        }
    }

使用:

string[] dt = strangeStr.SplitBy(new int[] { 2, 2, 4, 2, 2, 2, 2 }).ToArray();
public static IEnumerable<IEnumerable<T>> SplitEvery<T>(this IEnumerable<T> values, int n)
{
    var ls = values.Take(n);
    var rs = values.Skip(n);
    return ls.Any() ?
        Cons(ls, SplitEvery(rs, n)) : 
        Enumerable.Empty<IEnumerable<T>>();
}

public static IEnumerable<T> Cons<T>(T x, IEnumerable<T> xs)
{
    yield return x;
    foreach (var xi in xs)
        yield return xi;
}
        public static List<string> DevideByStringLength(string text, int chunkSize)
    {
        double a = (double)text.Length / chunkSize;
        var numberOfChunks = Math.Ceiling(a);

        Console.WriteLine($"{text.Length} | {numberOfChunks}");

        List<string> chunkList = new List<string>();
        for (int i = 0; i < numberOfChunks; i++)
        {
            string subString = string.Empty;
            if (i == (numberOfChunks - 1))
            {
                subString = text.Substring(chunkSize * i, text.Length - chunkSize * i);
                chunkList.Add(subString);
                continue;
            }
            subString = text.Substring(chunkSize * i, chunkSize);
            chunkList.Add(subString);
        }
        return chunkList;
    }

在多芬和康他汀的答案组合中……

static IEnumerable<string> WholeChunks(string str, int chunkSize) {
    for (int i = 0; i < str.Length; i += chunkSize) 
        yield return str.Substring(i, chunkSize);
}

这将适用于所有可以被分割成大量块的字符串,否则将抛出异常。

如果你想支持任意长度的字符串,你可以使用下面的代码:

static IEnumerable<string> ChunksUpto(string str, int maxChunkSize) {
    for (int i = 0; i < str.Length; i += maxChunkSize) 
        yield return str.Substring(i, Math.Min(maxChunkSize, str.Length-i));
}

然而,OP明确表示他不需要这个;它有点长,很难读,稍微慢一点。本着KISS和YAGNI的精神,我选择第一个选项:它可能是最有效的实现,而且非常简短、可读,而且重要的是,它会对不符合规范的输入抛出异常。

        List<string> chunks = new List<string>();
        var longString = new string('s', 3000);
        var chunkLength = 1273;
        var ratio = (double)longString.Length / chunkLength;
        var countOfChunks = Convert.ToByte(Math.Round(ratio, MidpointRounding.ToPositiveInfinity));

        for (byte i = 0; i < countOfChunks; i++)
        {
            var remainingLength = longString.Length - chunkLength * i;
            if (chunkLength > remainingLength)
                chunks.Add(longString.Substring(i * chunkLength, remainingLength));
            else
                chunks.Add(longString.Substring(i * chunkLength, chunkLength));
        }