2013-04-16 35 views
5

Điều tôi muốn làm là chia nhỏ số lần xuất hiện thứ n của một chuỗi (trong trường hợp này là "\ t"). Đây là mã tôi hiện đang sử dụng và nó chia tách trên mọi lần xuất hiện của "\ t".Làm thế nào để tách một chuỗi trên lần xuất hiện thứ n?

string[] items = input.Split(new char[] {'\t'}, StringSplitOptions.RemoveEmptyEntries); 

Nếu input = "một \ ttwo \ tthree \ tfour", mã của tôi trả về mảng của:

  • một
  • hai
  • ba
  • Bốn

Nhưng giả sử tôi muốn chia nó trên mọi "\ t" sau "\ t" thứ hai. Vì vậy, nó sẽ trả về:

  • một hai
  • ba
  • Bốn
+4

'\ t' không phải là một dòng mới; đó là một tab. Ý bạn là nói 'newline'? –

+3

câu hỏi của bạn không rõ ràng chỉnh sửa nó – gasroot

+0

Ồ, phải. Tôi có nghĩa là tab sau đó. Nhưng điều đó không quan trọng. Nó nên là cùng một phương pháp để phân chia bất kỳ chuỗi trên sự xuất hiện thứ n và làm thế nào để tôi làm điều đó? –

Trả lời

15

Không có gì được xây dựng tại là

Bạn có thể sử dụng hiện Split, sử dụng TakeSkip với. string.Join để xây dựng lại các phần mà ban đầu bạn có.

string[] items = input.Split(new char[] {'\t'}, 
          StringSplitOptions.RemoveEmptyEntries); 
string firstPart = string.Join("\t", items.Take(nthOccurrence)); 
string secondPart = string.Join("\t", items.Skip(nthOccurrence)) 

string[] everythingSplitAfterNthOccurence = items.Skip(nthOccurrence).ToArray(); 

Một cách khác là để lặp qua tất cả các ký tự trong chuỗi, tìm chỉ số của sự xuất hiện thứ n và chuỗi con trước và sau nó (hoặc tìm các chỉ số tiếp theo sau khi thứ n, chuỗi trên vv mà ... Vân vân...).

+1

Đây là tốt hơn tôi nhiều. Tôi không biết các tùy chọn 'Take' và' Skip'. Câu trả lời tuyệt vời ... – MoonKnight

+0

OP đã chỉnh sửa câu hỏi của anh ta, vì vậy dường như anh ta muốn chia nhỏ mọi lần xuất hiện * sau * thứ n, vì vậy yêu cầu đã thay đổi. –

+0

@MatthewWatson - Vâng, đủ dễ dàng. 'Bỏ qua' sẽ làm điều đó. – Oded

1

Có khả năng bạn sẽ phải chia nhỏ và kết hợp lại. Một cái gì đó như

int tabIndexToRemove = 3; 
string str = "My\tstring\twith\tloads\tof\ttabs"; 
string[] strArr = str.Split('\t'); 
int numOfTabs = strArr.Length - 1; 
if (tabIndexToRemove > numOfTabs) 
    throw new IndexOutOfRangeException(); 
str = String.Empty; 
for (int i = 0; i < strArr.Length; i++) 
    str += i == tabIndexToRemove - 1 ? 
     strArr[i] : String.Format("{0}\t", strArr[i]); 

Kết quả:

chuỗi My withloads các tab

Tôi hy vọng điều này sẽ giúp.

0
// Return a substring of str upto but not including 
// the nth occurence of substr 
function getNth(str, substr, n) { 
    var idx; 
    var i = 0; 
    var newstr = ''; 
    do { 
    idx = s.indexOf(c); 
    newstr += str.substring(0, idx); 
    str = str.substring(idx+1); 
    } while (++i < n && (newstr += substr)) 
    return newstr; 
} 
4

[EDIT] Sau khi đọc lại OP đã chỉnh sửa, tôi nhận ra điều này không làm những gì được yêu cầu. Điều này sẽ chia cho mọi mục tiêu thứ n; OP muốn chia trên mọi mục tiêu SAU sau lần thứ n.

Dù sao tôi cũng sẽ để nguyên điều này ở đây.


Nếu bạn đang sử dụng MoreLinq extensions, bạn có thể tận dụng phương pháp Batch của nó.

Mã của bạn sau đó sẽ trông như thế này:

string text = "1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\t13\t14\t15\t16\t17"; 

var splits = text.Split('\t').Batch(5); 

foreach (var split in splits) 
    Console.WriteLine(string.Join("", split)); 

Tôi muốn có thể chỉ cần sử dụng thực hiện Oded, nhưng tôi nghĩ rằng tôi muốn đăng bài này cho một cách tiếp cận khác.

Việc thực hiện Batch() trông như thế này:

public static class EnumerableExt 
{ 
    public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(this IEnumerable<TSource> source, int size) 
    { 
     TSource[] bucket = null; 
     var count = 0; 

     foreach (var item in source) 
     { 
      if (bucket == null) 
       bucket = new TSource[size]; 

      bucket[count++] = item; 

      if (count != size) 
       continue; 

      yield return bucket; 

      bucket = null; 
      count = 0; 
     } 

     if (bucket != null && count > 0) 
      yield return bucket.Take(count); 
    } 
} 
+1

+1 Hàng loạt rất tuyệt! – MoonKnight

Các vấn đề liên quan