也许是一个基本的问题,但是让我们说我有一个长度为2000个字符的字符串,我需要将此字符串拆分为每个最多512个字符的块。

有没有一个很好的方法,比如循环左右这样做?

有帮助吗?

解决方案

这样的事情:

private IList<string> SplitIntoChunks(string text, int chunkSize)
{
    List<string> chunks = new List<string>();
    int offset = 0;
    while (offset < text.Length)
    {
        int size = Math.Min(chunkSize, text.Length - offset);
        chunks.Add(text.Substring(offset, size));
        offset += size;
    }
    return chunks;
}

或者只是迭代:

private IEnumerable<string> SplitIntoChunks(string text, int chunkSize)
{
    int offset = 0;
    while (offset < text.Length)
    {
        int size = Math.Min(chunkSize, text.Length - offset);
        yield return text.Substring(offset, size);
        offset += size;
    }
}

请注意,这会拆分成UTF-16代码单元的块,这与分割成Unicode代码点的块不完全相同,而这些代码点又可能与分割成字形块不同。

其他提示

虽然这个问题同时有一个公认的答案,但这里有一个简短的版本,有正则表达式的帮助。纯粹主义者可能不喜欢它(可以理解)但是当你需要一个快速的解决方案并且你对正则表达式很方便时,就可以了。令人惊讶的是,表现相当不错:

string [] split = Regex.Split(yourString, @"(?<=\G.{512})");

它做什么?消极向后看并用\G记住最后一个位置。它也将捕获最后一位,即使它不能被512分割。

使用Jon的实现和 yield 关键字。

IEnumerable<string> Chunks(string text, int chunkSize)
{
    for (int offset = 0; offset < text.Length; offset += chunkSize)
    {
        int size = Math.Min(chunkSize, text.Length - offset);
        yield return text.Substring(offset, size);
    }
}
static IEnumerable<string> Split(string str, int chunkSize)    
{   
    int len = str.Length;
    return Enumerable.Range(0, len / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize));    
}

来源:将字符串拆分成块一定规模

基于string类型实现IEnumerable<char>的事实,我敢于提供更多LINQified版本的Jon解决方案:

private IList<string> SplitIntoChunks(string text, int chunkSize)
{
    var chunks = new List<string>();
    int offset = 0;
    while(offset < text.Length) {
        chunks.Add(new string(text.Skip(offset).Take(chunkSize).ToArray()));
        offset += chunkSize;
    }
    return chunks;
}

大多数答案可能都有相同的缺陷。 如果文本为空,则不会产生任何结果。 我们(我)期望至少回到那个空字符串(与不在字符串中的字符串上的拆分行为相同,这将返回一个项目:给定字符串)

所以我们应该至少循环一次(基于Jon的代码):

IEnumerable<string> SplitIntoChunks (string text, int chunkSize)
{
    int offset = 0;
    do
    {
        int size = Math.Min (chunkSize, text.Length - offset);
        yield return text.Substring (offset, size);
        offset += size;
    } while (offset < text.Length);
}

或使用for(已编辑:在玩弄了一点之后,我找到了一种更好的方法来处理 chunkSize大于文本的情况):

IEnumerable<string> SplitIntoChunks (string text, int chunkSize)
{
    if (text.Length <= chunkSize)
        yield return text;
    else
    {
        var chunkCount = text.Length / chunkSize;
        var remainingSize = text.Length % chunkSize;

        for (var offset = 0; offset < chunkCount; ++offset)
            yield return text.Substring (offset * chunkSize, chunkSize);

        // yield remaining text if any
        if (remainingSize != 0)
            yield return text.Substring (chunkCount * chunkSize, remainingSize);
    }
}

也可以与do / while循环一起使用;)

通用扩展方法:

using System;
using System.Collections.Generic;
using System.Linq;

public static class IEnumerableExtensions
{
  public static IEnumerable<IEnumerable<T>> SplitToChunks<T> (this IEnumerable<T> coll, int chunkSize)
  {
    int skipCount = 0;
    while (coll.Skip (skipCount).Take (chunkSize) is IEnumerable<T> part && part.Any ())
    {
      skipCount += chunkSize;
      yield return part;
    }
  }
}

class Program
{
  static void Main (string[] args)
  {
    var col = Enumerable.Range(1,1<<10);
    var chunks = col.SplitToChunks(8);

    foreach (var c in chunks.Take (200))
    {
      Console.WriteLine (string.Join (" ", c.Select (n => n.ToString ("X4"))));
    }

    Console.WriteLine ();
    Console.WriteLine ();

    "Split this text into parts that are fifteen characters in length, surrounding each part with single quotes and output each into the console on seperate lines."
      .SplitToChunks (15)
      .Select(p => $"'{string.Concat(p)}'")
      .ToList ()
      .ForEach (p => Console.WriteLine (p));

    Console.ReadLine ();
  }
}

喜欢什么?

Calculate eachLength = StringLength / WantedCharLength
Then for (int i = 0; i < StringLength; i += eachLength)
SubString (i, eachLength);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top