2012-04-16 34 views
0

我有一个由换行符分隔的大字符串。该字符串包含100行。我想将这些行分成小块,也就是说基于换行符的20块。在c中将大字符串拆分为更小的块#

比方说,字符串变量是这样的,

一号线
这是2号线
3号线在这里
我线路4

现在我想分割这个大字符串变量成小块的结果应该是2个字符串作为,

行1
这是行2


3号线在这里
我线路4

使用分割功能,我没有得到预期的结果。请帮助我实现这一点。

由于提前,
维杰

+0

拆分换行会给你4个字符串,而不是两个...你为什么期望有什么不同? – MrLane 2012-04-16 05:36:24

+0

分割会给你4条线。你不要合并这两个字符串n把它放在一个新的数组中。 – Akanksha 2012-04-16 05:38:29

+0

使用分割和字符串bulider类。一旦这会帮助你 – joshua 2012-04-16 05:42:00

回答

2

简单的方法(在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; 
} 
0

由换行符拆分字符串。 然后在使用字符串的同时合并/获取字符串的数量。

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; 
    } 
} 
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的长度为奇数

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() 
} 
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包装)。