我有一个由换行符分隔的大字符串。该字符串包含100行。我想将这些行拆分成小块,例如20块也基于换行符。
假设字符串变量是这样的,
Line1
这是line2
Line3在这里是我是Line4
现在我想把这个大字符串变量分成2个小块。结果应该是2个字符串,
Line1
这是第2行
第3行在这里是我是Line4
使用Split功能,我没有得到预期的结果。请帮助我实现这一目标。
提前致谢,
维杰
答案 0 :(得分:3)
简单方法(在Environment.NewLine上拆分,然后循环并追加):
public static List<string> GetStringSegments(string originalString, int linesPerSegment)
{
List<string> segments = new List<string>();
string[] allLines = originalString.Split(new string[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
int linesProcessed = 0;
for (int i = 0; i < allLines.Length; i++)
{
sb.AppendLine(allLines[i]);
linesProcessed++;
if (linesProcessed == linesPerSegment
|| i == allLines.Length-1)
{
segments.Add(sb.ToString());
sb.Clear();
inesProcessed = 0;
}
}
return segments;
}
上述方法效率稍低,因为它需要先将字符串拆分为单独的行,这会产生不必要的字符串。一串1000行将创建一个包含1000个字符串的数组。如果我们只是扫描字符串并搜索\n
:
public static List<string> GetStringSegments(string original, int linesPerSegment)
{
List<string> segments = new List<string>();
int startIndex = 0;
int newLinesEncountered = 0;
for (int i = 0; i < original.Length; i++)
{
if (original[i] == '\n')
{
newLinesEncountered++;
}
if (newLinesEncountered == linesPerSegment
|| i == original.Length - 1)
{
segments.Add(original.Substring(startIndex, (i - startIndex + 1)));
startIndex = i + 1;
newLinesEncountered = 0;
}
}
return segments;
}
答案 1 :(得分:2)
您可以使用http://www.make-awesome.com/2010/08/batch-or-partition-a-collection-with-linq
中的批处理运算符string s = "[YOUR DATA]";
var lines = s.Split(new[]{Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
foreach(var batch in lines.Batch(20))
{
foreach(batchLine in batch)
{
Console.Writeline(batchLine);
}
}
static class LinqEx
{
// from http://www.make-awesome.com/2010/08/batch-or-partition-a-collection-with-linq
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> collection,
int batchSize)
{
List<T> nextbatch = new List<T>(batchSize);
foreach (T item in collection)
{
nextbatch.Add(item);
if (nextbatch.Count == batchSize)
{
yield return nextbatch;
nextbatch = new List<T>(batchSize);
}
}
if (nextbatch.Count > 0)
yield return nextbatch;
}
}
答案 2 :(得分:1)
正如几位人士所提到的,使用string.Split
会将整个字符串拆分为内存,这可能是一个分配繁重的操作。这就是为什么我们有TextReader
类及其后代,应该提供更好的内存性能,并且逻辑上也可能更清晰:
using (var reader = new StringReader(myString))
{
do
{
StringBuilder newString = null;
StringWriter newStringWriter = null;
if (lineCounter % 20 == 0)
{
newString = new StringBuilder();
newStringWriter = new StringWriter(newString);
newStringCollection.Add(newString);
}
string line = reader.ReadLine();
if (!string.isNullOrEmpty(line))
{
newStringWriter.WriteLine(line);
lineCounter++;
}
}
while (line != null)
}
我们正在使用StringReader
来读取我们的大字符串,一次一行。相应的StringWriter
将这些行写入新字符串,一次一行。每20行后,我们会开始一个新的StringBuilder
(以及相应的StringWriter
包装器)。
答案 3 :(得分:0)
按换行符分割字符串。 然后在使用字符串时合并/获取字符串数。
答案 4 :(得分:0)
string s = "Line1\nThis is line2 \nLine3 is here\nI am Line4";
string [] str = s.split('\n');
List<String> str1 = new List<String>();
for(int i=0; i<str.Length; i+=2)
{
string ss = str[i];
if(i+1 <str.Length)
ss += '\n' + str[i+1];
str1.Add(ss);
}
str = str1.ToArray();
如果在循环内检查了条件,因为str的长度可能是奇数
答案 5 :(得分:0)
var strAray = myLongString.Split('\n').ToList();
var skip=0;
var take=20;
var chunk = strAray.Skip(skip).Take(take).ToList();
While(chunk.Count >0)
{
foreach(var line in chunk)
{
// use line string
}
skip++;
chunk = strAray.Skip(skip).Take(take).ToList()
}