假设我有一个字符串:

string str = "1111222233334444"; 

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

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

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

当前回答

我在João的解决方案基础上做了一些改进。 我所做的不同之处在于,在我的方法中,你实际上可以指定是否要返回带有剩余字符的数组,或者如果结束字符不匹配所需的块长度,你是否要截断它们,我认为这是相当灵活的,代码相当直接:

using System;
using System.Linq;
using System.Text.RegularExpressions;

namespace SplitFunction
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "hello, how are you doing today?";
            string[] chunks = SplitIntoChunks(text, 3,false);
            if (chunks != null)
            {
                chunks.ToList().ForEach(e => Console.WriteLine(e));
            }

            Console.ReadKey();
        }

        private static string[] SplitIntoChunks(string text, int chunkSize, bool truncateRemaining)
        {
            string chunk = chunkSize.ToString(); 
            string pattern = truncateRemaining ? ".{" + chunk + "}" : ".{1," + chunk + "}";

            string[] chunks = null;
            if (chunkSize > 0 && !String.IsNullOrEmpty(text))
                chunks = (from Match m in Regex.Matches(text,pattern)select m.Value).ToArray(); 

            return chunks;
        }     
    }
}

其他回答

从。net 6开始,我们还可以使用Chunk方法:

var result = str
    .Chunk(4)
    .Select(x => new string(x))
    .ToList();

它基于@dove解决方案,但作为扩展方法实现。

好处:

扩展方法 涵盖角落案例 分割字符串与任何字符:数字,字母,其他符号

Code

public static class EnumerableEx
{    
    public static IEnumerable<string> SplitBy(this string str, int chunkLength)
    {
        if (String.IsNullOrEmpty(str)) throw new ArgumentException();
        if (chunkLength < 1) throw new ArgumentException();

        for (int i = 0; i < str.Length; i += chunkLength)
        {
            if (chunkLength + i > str.Length)
                chunkLength = str.Length - i;

            yield return str.Substring(i, chunkLength);
        }
    }
}

使用

var result = "bobjoecat".SplitBy(3); // bob, joe, cat

为简洁起见,删除了单元测试(请参阅以前的修订版)

为什么不是循环?这里有一些东西可以很好地做到这一点:

        string str = "111122223333444455";
        int chunkSize = 4;
        int stringLength = str.Length;
        for (int i = 0; i < stringLength ; i += chunkSize)
        {
            if (i + chunkSize > stringLength) chunkSize = stringLength  - i;
            Console.WriteLine(str.Substring(i, chunkSize));

        }
        Console.ReadLine();

我不知道你会如何处理字符串不是因子4的情况,但不是说你的想法是不可能的,只是想知道它的动机,如果一个简单的for循环做得很好?显然,上面的内容可以被清除,甚至可以作为扩展方法加入。

或者正如评论中提到的,你知道它是/4

str = "1111222233334444";
for (int i = 0; i < stringLength; i += chunkSize) 
  {Console.WriteLine(str.Substring(i, chunkSize));} 

这样写一行代码怎么样?

List<string> result = new List<string>(Regex.Split(target, @"(?<=\G.{4})", RegexOptions.Singleline));

对于这个正则表达式,最后一个块是否小于4个字符并不重要,因为它只查看它后面的字符。

我知道这不是最有效的解决方案,但我不得不把它扔出去。

static IEnumerable<string> Split(string str, int chunkSize)
{
    return Enumerable.Range(0, str.Length / chunkSize)
        .Select(i => str.Substring(i * chunkSize, chunkSize));
}

请注意,可能需要额外的代码来优雅地处理边缘情况(null或空输入字符串,chunkSize == 0,输入字符串长度不能被chunkSize整除,等等)。最初的问题没有为这些边缘情况指定任何需求,在现实生活中,需求可能会有所不同,因此它们超出了这个答案的范围。