代码之家  ›  专栏  ›  技术社区  ›  janhartmann

将字符串拆分为512个字符的块

  •  10
  • janhartmann  · 技术社区  · 15 年前

    也许是一个基本的问题,但假设我有一个2000个字符长的字符串,我需要将这个字符串拆分为最多512个字符块。

    有没有一个很好的方法,比如循环?

    8 回复  |  直到 15 年前
        1
  •  20
  •   Jon Skeet    9 年前

    像这样:

    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代码点的块不同,后者可能与拆分成字形块不同。

        2
  •  3
  •   Abel    15 年前

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

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

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

        3
  •  3
  •   Community CDub    9 年前

    使用jon的实现和 产量 关键字。

    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);
        }
    }
    
        4
  •  1
  •   Community CDub    7 年前
    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));    
    }
    

    来源: Splitting a string into chunks of a certain size

        5
  •  1
  •   Konamiman    15 年前

    我敢提供乔恩解决方案的更线性化版本,基于以下事实: string 类型工具 IEnumerable<char> :

    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;
    }
    
        6
  •  1
  •   Sehnsucht    9 年前

    大多数答案可能都有相同的缺陷。 如果给出一个空文本,他们将什么也不会产生。 我们(i)希望至少能返回该空字符串(与不在字符串中的字符拆分行为相同,后者将返回一个项:给定的字符串)

    因此,我们应该始终至少循环一次(基于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);
    }
    

    或使用( 编辑 :这件事再多玩弄一点,我找到了一个更好的办法来处理这个案子。 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循环;)

        7
  •  0
  •   Patrick Artner    7 年前

    通用扩展方法:

    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 ();
      }
    }
    
        8
  •  -1
  •   Foxfire    15 年前

    像什么?

    Calculate eachLength = StringLength / WantedCharLength
    Then for (int i = 0; i < StringLength; i += eachLength)
    SubString (i, eachLength);