将字符串拆分为一定大小的块

时间:2009-09-20 10:55:25

标签: c# string

假设我有一个字符串:

string str = "1111222233334444"; 

如何将此字符串分解为某种大小的块?

例如,将此值分解为4将返回字符串:

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

37 个答案:

答案 0 :(得分:199)

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整除,等等。最初的问题没有说明对这些边缘情况的任何要求,在现实生活中,要求可能会有所不同,因此它们超出了这个答案的范围。

答案 1 :(得分:123)

鸽子+康斯坦丁的答案组合......

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的精神,我会选择第一个选项:它可能是最有效的实现,而且它非常简短,可读,并且重要的是,它会导致不合格输入的异常。

答案 2 :(得分:49)

为什么不循环?这是一件可以做得很好的事情:

        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));} 

答案 3 :(得分:36)

使用正则表达式 Linq

List<string> groups = (from Match m in Regex.Matches(str, @"\d{4}")
                       select m.Value).ToList();

我发现这更具可读性,但这只是个人观点。它也可以是单行:)。

答案 4 :(得分:29)

这基于@dove solution,但作为扩展方法实现。

优点:

  • 扩展方法
  • 涵盖角落案例
  • 使用任何字符拆分字符串:数字,字母,其他符号

代码

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

为简洁起见,删除了单元测试(参见previous revision

答案 5 :(得分:19)

这对于一个班轮怎么样?

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

使用这个正则表达式,如果最后一个块少于四个字符并不重要,因为它只查看它背后的字符。

我确信这不是最有效的解决方案,但我只是不得不把它扔掉。

答案 6 :(得分:8)

它不漂亮而且它不快,但它有效,它是一个单行,它是LINQy:

List<string> a = text.Select((c, i) => new { Char = c, Index = i }).GroupBy(o => o.Index / 4).Select(g => new String(g.Select(o => o.Char).ToArray())).ToList();

答案 7 :(得分:7)

我最近不得不写一些能在工作中完成这项任务的东西,所以我想我会将解决方案发布到这个问题上。作为一个额外的好处,这个解决方案的功能提供了一种方法,以相反的方向分割字符串,它正确处理unicode字符,如上面Marvin Pinto所述。所以,这是:

using System;
using Extensions;

namespace TestCSharp
{
    class Program
    {
        static void Main(string[] args)
        {    
            string asciiStr = "This is a string.";
            string unicodeStr = "これは文字列です。";

            string[] array1 = asciiStr.Split(4);
            string[] array2 = asciiStr.Split(-4);

            string[] array3 = asciiStr.Split(7);
            string[] array4 = asciiStr.Split(-7);

            string[] array5 = unicodeStr.Split(5);
            string[] array6 = unicodeStr.Split(-5);
        }
    }
}

namespace Extensions
{
    public static class StringExtensions
    {
        /// <summary>Returns a string array that contains the substrings in this string that are seperated a given fixed length.</summary>
        /// <param name="s">This string object.</param>
        /// <param name="length">Size of each substring.
        ///     <para>CASE: length &gt; 0 , RESULT: String is split from left to right.</para>
        ///     <para>CASE: length == 0 , RESULT: String is returned as the only entry in the array.</para>
        ///     <para>CASE: length &lt; 0 , RESULT: String is split from right to left.</para>
        /// </param>
        /// <returns>String array that has been split into substrings of equal length.</returns>
        /// <example>
        ///     <code>
        ///         string s = "1234567890";
        ///         string[] a = s.Split(4); // a == { "1234", "5678", "90" }
        ///     </code>
        /// </example>            
        public static string[] Split(this string s, int length)
        {
            System.Globalization.StringInfo str = new System.Globalization.StringInfo(s);

            int lengthAbs = Math.Abs(length);

            if (str == null || str.LengthInTextElements == 0 || lengthAbs == 0 || str.LengthInTextElements <= lengthAbs)
                return new string[] { str.ToString() };

            string[] array = new string[(str.LengthInTextElements % lengthAbs == 0 ? str.LengthInTextElements / lengthAbs: (str.LengthInTextElements / lengthAbs) + 1)];

            if (length > 0)
                for (int iStr = 0, iArray = 0; iStr < str.LengthInTextElements && iArray < array.Length; iStr += lengthAbs, iArray++)
                    array[iArray] = str.SubstringByTextElements(iStr, (str.LengthInTextElements - iStr < lengthAbs ? str.LengthInTextElements - iStr : lengthAbs));
            else // if (length < 0)
                for (int iStr = str.LengthInTextElements - 1, iArray = array.Length - 1; iStr >= 0 && iArray >= 0; iStr -= lengthAbs, iArray--)
                    array[iArray] = str.SubstringByTextElements((iStr - lengthAbs < 0 ? 0 : iStr - lengthAbs + 1), (iStr - lengthAbs < 0 ? iStr + 1 : lengthAbs));

            return array;
        }
    }
}

此外,这是运行此代码的结果的图像链接:http://i.imgur.com/16Iih.png

答案 8 :(得分:5)

这比使用LINQ或此处使用的其他方法更快更有效。

public static IEnumerable<string> Splice(this string s, int spliceLength)
{
    if (s == null)
        throw new ArgumentNullException("s");
    if (spliceLength < 1)
        throw new ArgumentOutOfRangeException("spliceLength");

    if (s.Length == 0)
        yield break;
    var start = 0;
    for (var end = spliceLength; end < s.Length; end += spliceLength)
    {
        yield return s.Substring(start, spliceLength);
        start = end;
    }
    yield return s.Substring(start);
}

答案 9 :(得分:4)

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;
}

答案 10 :(得分:4)

您可以使用Jon Skeet的morelinq。使用Batch之类的:

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

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

输出:

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

它将给出:

1111
2222
3333
4444

答案 11 :(得分:3)

static IEnumerable<string> Split(string str, double chunkSize)
{
    return Enumerable.Range(0, (int) Math.Ceiling(str.Length/chunkSize))
       .Select(i => new string(str
           .Skip(i * (int)chunkSize)
           .Take((int)chunkSize)
           .ToArray()));
}

和另一种方法:

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

public class Program
{
    public static void Main()
    {

        var x = "Hello World";
        foreach(var i in x.ChunkString(2)) Console.WriteLine(i);
    }
}

public static class Ext{
    public static IEnumerable<string> ChunkString(this string val, int chunkSize){
        return val.Select((x,i) => new {Index = i, Value = x})
                  .GroupBy(x => x.Index/chunkSize, x => x.Value)
                  .Select(x => string.Join("",x));
    }
}

答案 12 :(得分:3)

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

   if (str.Length % chunkSize > 0)
        retVal = retVal.Append(str.Substring(str.Length / chunkSize * chunkSize, str.Length % chunkSize));

   return retVal;
}

它可以正确处理不能被chunkSize整除的输入字符串长度。

请注意,可能需要其他代码才能正常处理边缘情况(空或空输入字符串,chunkSize == 0)。

答案 13 :(得分:3)

简单和简短:

// this means match a space or not a space (anything) up to 4 characters
var lines = Regex.Matches(str, @"[\s\S]{0,4}").Cast<Match>().Select(x => x.Value);

答案 14 :(得分:3)

六年后o_O

仅仅因为

    public static IEnumerable<string> Split(this string str, int chunkSize, bool remainingInFront)
    {
        var count = (int) Math.Ceiling(str.Length/(double) chunkSize);
        Func<int, int> start = index => remainingInFront ? str.Length - (count - index)*chunkSize : index*chunkSize;
        Func<int, int> end = index => Math.Min(str.Length - Math.Max(start(index), 0), Math.Min(start(index) + chunkSize - Math.Max(start(index), 0), chunkSize));
        return Enumerable.Range(0, count).Select(i => str.Substring(Math.Max(start(i), 0),end(i)));
    }

    private static Func<bool, int, int, int, int, int> start = (remainingInFront, length, count, index, size) =>
        remainingInFront ? length - (count - index) * size : index * size;

    private static Func<bool, int, int, int, int, int, int> end = (remainingInFront, length, count, index, size, start) =>
        Math.Min(length - Math.Max(start, 0), Math.Min(start + size - Math.Max(start, 0), size));

    public static IEnumerable<string> Split(this string str, int chunkSize, bool remainingInFront)
    {
        var count = (int)Math.Ceiling(str.Length / (double)chunkSize);
        return Enumerable.Range(0, count).Select(i => str.Substring(
            Math.Max(start(remainingInFront, str.Length, count, i, chunkSize), 0),
            end(remainingInFront, str.Length, count, i, chunkSize, start(remainingInFront, str.Length, count, i, chunkSize))
        ));
    }

AFAIK处理所有边缘案件。

Console.WriteLine(string.Join(" ", "abc".Split(2, false))); // ab c
Console.WriteLine(string.Join(" ", "abc".Split(2, true))); // a bc
Console.WriteLine(string.Join(" ", "a".Split(2, true))); // a
Console.WriteLine(string.Join(" ", "a".Split(2, false))); // a

答案 15 :(得分:2)

最佳,最简单和通用答案:)。

    string originalString = "1111222233334444";
    List<string> test = new List<string>();
    int chunkSize = 4; // change 4 with the size of strings you want.
    for (int i = 0; i < originalString.Length; i = i + chunkSize)
    {
        if (originalString.Length - i >= chunkSize)
            test.Add(originalString.Substring(i, chunkSize));
        else
            test.Add(originalString.Substring(i,((originalString.Length - i))));
    }

答案 16 :(得分:2)

我知道问题已经存在多年了,但这是一个Rx实现。它可以立即解决length % chunkSize != 0问题:

   public static IEnumerable<string> Chunkify(this string input, int size)
        {
            if(size < 1)
                throw new ArgumentException("size must be greater than 0");

            return input.ToCharArray()
                .ToObservable()
                .Buffer(size)            
                .Select(x => new string(x.ToArray()))
                .ToEnumerable();
        }

答案 17 :(得分:2)

我个人更喜欢我的解决方案: - )

它处理:

  • 字符串长度是块大小的倍数。
  • 字符串长度不是块大小的倍数。
  • 小于块大小的字符串长度。
  • NULL和空字符串(抛出异常)。
  • 小于1的块大小(抛出异常)。

它作为扩展方法实现,它计算预先生成的块数。它检查最后一个块,因为如果文本长度不是倍数,则需要更短。干净,简短,易于理解......并且有效!

    public static string[] Split(this string value, int chunkSize)
    {
        if (string.IsNullOrEmpty(value)) throw new ArgumentException("The string cannot be null.");
        if (chunkSize < 1) throw new ArgumentException("The chunk size should be equal or greater than one.");

        int remainder;
        int divResult = Math.DivRem(value.Length, chunkSize, out remainder);

        int numberOfChunks = remainder > 0 ? divResult + 1 : divResult;
        var result = new string[numberOfChunks];

        int i = 0;
        while (i < numberOfChunks - 1)
        {
            result[i] = value.Substring(i * chunkSize, chunkSize);
            i++;
        }

        int lastChunkSize = remainder > 0 ? remainder : chunkSize;
        result[i] = value.Substring(i * chunkSize, lastChunkSize);

        return result;
    }

答案 18 :(得分:2)

如果正在分块的字符串需要支持所有Unicode字符,那么这是一个重要提示。

如果字符串支持等国际字符,则使用System.Globalization.StringInfo类拆分字符串。使用StringInfo,您可以根据文本元素的数量拆分字符串。

string internationalString = '';

上面的字符串长度为2,因为String.Length属性返回此实例中的Char对象数,而不是Unicode字符数。

答案 19 :(得分:2)

List<string> SplitString(int chunk, string input)
{
    List<string> list = new List<string>();
    int cycles = input.Length / chunk;

    if (input.Length % chunk != 0)
        cycles++;

    for (int i = 0; i < cycles; i++)
    {
        try
        {
            list.Add(input.Substring(i * chunk, chunk));
        }
        catch
        {
            list.Add(input.Substring(i * chunk));
        }
    }
    return list;
}

答案 20 :(得分:2)

我认为这是一个直截了当的答案:

public static IEnumerable<string> Split(this string str, int chunkSize)
    {
        if(string.IsNullOrEmpty(str) || chunkSize<1)
            throw new ArgumentException("String can not be null or empty and chunk size should be greater than zero.");
        var chunkCount = str.Length / chunkSize + (str.Length % chunkSize != 0 ? 1 : 0);
        for (var i = 0; i < chunkCount; i++)
        {
            var startIndex = i * chunkSize;
            if (startIndex + chunkSize >= str.Length)
                yield return str.Substring(startIndex);
            else
                yield return str.Substring(startIndex, chunkSize);
        }
    }

它涵盖边缘案例。

答案 21 :(得分:1)

我不记得是谁给了我这个,但它很有效。我快速测试了多种方法将可枚举类型分成组。用法就是这样......

List<string> Divided = Source3.Chunk(24).Select(Piece => string.Concat<char>(Piece)).ToList();

扩展代码看起来像这样......

#region Chunk Logic
private class ChunkedEnumerable<T> : IEnumerable<T>
{
    class ChildEnumerator : IEnumerator<T>
    {
        ChunkedEnumerable<T> parent;
        int position;
        bool done = false;
        T current;


        public ChildEnumerator(ChunkedEnumerable<T> parent)
        {
            this.parent = parent;
            position = -1;
            parent.wrapper.AddRef();
        }

        public T Current
        {
            get
            {
                if (position == -1 || done)
                {
                    throw new InvalidOperationException();
                }
                return current;

            }
        }

        public void Dispose()
        {
            if (!done)
            {
                done = true;
                parent.wrapper.RemoveRef();
            }
        }

        object System.Collections.IEnumerator.Current
        {
            get { return Current; }
        }

        public bool MoveNext()
        {
            position++;

            if (position + 1 > parent.chunkSize)
            {
                done = true;
            }

            if (!done)
            {
                done = !parent.wrapper.Get(position + parent.start, out current);
            }

            return !done;

        }

        public void Reset()
        {
            // per http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.reset.aspx
            throw new NotSupportedException();
        }
    }

    EnumeratorWrapper<T> wrapper;
    int chunkSize;
    int start;

    public ChunkedEnumerable(EnumeratorWrapper<T> wrapper, int chunkSize, int start)
    {
        this.wrapper = wrapper;
        this.chunkSize = chunkSize;
        this.start = start;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return new ChildEnumerator(this);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

}
private class EnumeratorWrapper<T>
{
    public EnumeratorWrapper(IEnumerable<T> source)
    {
        SourceEumerable = source;
    }
    IEnumerable<T> SourceEumerable { get; set; }

    Enumeration currentEnumeration;

    class Enumeration
    {
        public IEnumerator<T> Source { get; set; }
        public int Position { get; set; }
        public bool AtEnd { get; set; }
    }

    public bool Get(int pos, out T item)
    {

        if (currentEnumeration != null && currentEnumeration.Position > pos)
        {
            currentEnumeration.Source.Dispose();
            currentEnumeration = null;
        }

        if (currentEnumeration == null)
        {
            currentEnumeration = new Enumeration { Position = -1, Source = SourceEumerable.GetEnumerator(), AtEnd = false };
        }

        item = default(T);
        if (currentEnumeration.AtEnd)
        {
            return false;
        }

        while (currentEnumeration.Position < pos)
        {
            currentEnumeration.AtEnd = !currentEnumeration.Source.MoveNext();
            currentEnumeration.Position++;

            if (currentEnumeration.AtEnd)
            {
                return false;
            }

        }

        item = currentEnumeration.Source.Current;

        return true;
    }

    int refs = 0;

    // needed for dispose semantics 
    public void AddRef()
    {
        refs++;
    }

    public void RemoveRef()
    {
        refs--;
        if (refs == 0 && currentEnumeration != null)
        {
            var copy = currentEnumeration;
            currentEnumeration = null;
            copy.Source.Dispose();
        }
    }
}
/// <summary>Speed Checked.  Works Great!</summary>
public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
    if (chunksize < 1) throw new InvalidOperationException();

    var wrapper = new EnumeratorWrapper<T>(source);

    int currentPos = 0;
    T ignore;
    try
    {
        wrapper.AddRef();
        while (wrapper.Get(currentPos, out ignore))
        {
            yield return new ChunkedEnumerable<T>(wrapper, chunksize, currentPos);
            currentPos += chunksize;
        }
    }
    finally
    {
        wrapper.RemoveRef();
    }
}
#endregion

答案 22 :(得分:1)

    public static List<string> SplitByMaxLength(this string str)
    {
        List<string> splitString = new List<string>();

        for (int index = 0; index < str.Length; index += MaxLength)
        {
            splitString.Add(str.Substring(index, Math.Min(MaxLength, str.Length - index)));
        }

        return splitString;
    }

答案 23 :(得分:1)

class StringHelper
{
    static void Main(string[] args)
    {
        string str = "Hi my name is vikas bansal and my email id is bansal.vks@gmail.com";
        int offSet = 10;

        List<string> chunks = chunkMyStr(str, offSet);

        Console.Read();
    }

    static List<string> chunkMyStr(string str, int offSet)
    {


        List<string> resultChunks = new List<string>();

        for (int i = 0; i < str.Length; i += offSet)
        {
            string temp = str.Substring(i, (str.Length - i) > offSet ? offSet : (str.Length - i));
            Console.WriteLine(temp);
            resultChunks.Add(temp);


        }

        return resultChunks;
    }
}

答案 24 :(得分:1)

已修改(现在它接受任何非空string任何肯定chunkSize Konstantin Spirin 溶液:

public static IEnumerable<String> Split(String value, int chunkSize) {
  if (null == value)
    throw new ArgumentNullException("value");
  else if (chunkSize <= 0)
    throw new ArgumentOutOfRangeException("chunkSize", "Chunk size should be positive");

  return Enumerable
    .Range(0, value.Length / chunkSize + ((value.Length % chunkSize) == 0 ? 0 : 1))
    .Select(index => (index + 1) * chunkSize < value.Length 
      ? value.Substring(index * chunkSize, chunkSize)
      : value.Substring(index * chunkSize));
}

试验:

  String source = @"ABCDEF";

  // "ABCD,EF"
  String test1 = String.Join(",", Split(source, 4));
  // "AB,CD,EF"
  String test2 = String.Join(",", Split(source, 2));
  // "ABCDEF"
  String test3 = String.Join(",", Split(source, 123));

答案 25 :(得分:1)

我略微积累了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;
        }     
    }
}

答案 26 :(得分:1)

我把它带到了另一个层次。夹头很容易,但就我而言,我也需要完整的单词。想想我会发布它,以防万一有人需要类似的东西。

static IEnumerable<string> Split(string orgString, int chunkSize, bool wholeWords = true)
{
    if (wholeWords)
    {
        List<string> result = new List<string>();
        StringBuilder sb = new StringBuilder();

        if (orgString.Length > chunkSize)
        {
            string[] newSplit = orgString.Split(' ');
            foreach (string str in newSplit)
            {
                if (sb.Length != 0)
                    sb.Append(" ");

                if (sb.Length + str.Length > chunkSize)
                {
                    result.Add(sb.ToString());
                    sb.Clear();
                }

                sb.Append(str);
            }

            result.Add(sb.ToString());
        }
        else
            result.Add(orgString);

        return result;
    }
    else
        return new List<string>(Regex.Split(orgString, @"(?<=\G.{" + chunkSize + "})", RegexOptions.Singleline));
}

基于以下评论的结果:

string msg = "336699AABBCCDDEEFF";
foreach (string newMsg in Split(msg, 2, false))
{
    Console.WriteLine($">>{newMsg}<<");
}

Console.ReadKey();

结果:

>>33<<
>>66<<
>>99<<
>>AA<<
>>BB<<
>>CC<<
>>DD<<
>>EE<<
>>FF<<
>><<

另一种拉动方式:

List<string> splitData = (List<string>)Split(msg, 2, false);

for (int i = 0; i < splitData.Count - 1; i++)
{
    Console.WriteLine($">>{splitData[i]}<<");
}

Console.ReadKey();

新结果:

>>33<<
>>66<<
>>99<<
>>AA<<
>>BB<<
>>CC<<
>>DD<<
>>EE<<
>>FF<<

答案 27 :(得分:1)

略微更改以返回大小不等于chunkSize的部件

public static IEnumerable<string> Split(this string str, int chunkSize)
    {
        var splits = new List<string>();
        if (str.Length < chunkSize) { chunkSize = str.Length; }
        splits.AddRange(Enumerable.Range(0, str.Length / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize)));
        splits.Add(str.Length % chunkSize > 0 ? str.Substring((str.Length / chunkSize) * chunkSize, str.Length - ((str.Length / chunkSize) * chunkSize)) : string.Empty);
        return (IEnumerable<string>)splits;
    }

答案 28 :(得分:0)

        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));
        }

答案 29 :(得分:0)

在即将推出的 .NET 6 中,我们还可以使用新的 Chunk 方法:

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

答案 30 :(得分:0)

        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;
    }

答案 31 :(得分:0)

基于其他海报的答案,以及一些使用样本:

public static string FormatSortCode(string sortCode)
{
    return ChunkString(sortCode, 2, "-");
}
public static string FormatIBAN(string iban)
{
    return ChunkString(iban, 4, "&nbsp;&nbsp;");
}

private static string ChunkString(string str, int chunkSize, string separator)
{
    var b = new StringBuilder();
    var stringLength = str.Length;
    for (var i = 0; i < stringLength; i += chunkSize)
    {
        if (i + chunkSize > stringLength) chunkSize = stringLength - i;
        b.Append(str.Substring(i, chunkSize));
        if (i+chunkSize != stringLength)
            b.Append(separator);
    }
    return b.ToString();
}

答案 32 :(得分:0)

这是我的2美分:

  IEnumerable<string> Split(string str, int chunkSize)
  {
     while (!string.IsNullOrWhiteSpace(str))
     {
        var chunk = str.Take(chunkSize).ToArray();
        str = str.Substring(chunk.Length);
        yield return new string(chunk);

     }

  }//Split

答案 33 :(得分:0)

static List<string> GetChunks(string value, int chunkLength)
{
    var res = new List<string>();
    int count = (value.Length / chunkLength) + (value.Length % chunkLength > 0 ? 1 : 0);
    Enumerable.Range(0, count).ToList().ForEach(f => res.Add(value.Skip(f * chunkLength).Take(chunkLength).Select(z => z.ToString()).Aggregate((a,b) => a+b)));
    return res;
}

demo

答案 34 :(得分:0)

如果需要分割几个不同的长度: 例如,你有日期和时间指定格式字符串strangeStr = "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();

答案 35 :(得分:0)

这也可以通过这种方式完成

        string actualString = "1111222233334444";
        var listResult = new List<string>();
        int groupingLength = actualString.Length % 4;
        if (groupingLength > 0)
            listResult.Add(actualString.Substring(0, groupingLength));
        for (int i = groupingLength; i < actualString.Length; i += 4)
        {
            listResult.Add(actualString.Substring(i, 4));
        }

        foreach(var res in listResult)
        {
            Console.WriteLine(res);
        }
        Console.Read();

答案 36 :(得分:0)

使用IX library

中的缓冲区扩展
    static IEnumerable<string> Split( this string str, int chunkSize )
    {
        return str.Buffer(chunkSize).Select(l => String.Concat(l));
    }