拆分512个char块中的字符串

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

有没有一个好方法,像一个循环左右这样做?

像这样的东西:

 private IList SplitIntoChunks(string text, int chunkSize) { List chunks = new List(); 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 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 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 Split(string str, int chunkSize) { int len = str.Length; return Enumerable.Range(0, len / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize)); } 

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

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

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

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

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

 IEnumerable 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 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> SplitToChunks (this IEnumerable coll, int chunkSize) { int skipCount = 0; while (coll.Skip (skipCount).Take (chunkSize) is IEnumerable 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);