Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split a string on the nth occurrence?

Tags:

c#

What I want to do is to split on the nth occurrence of a string (in this case it's "\t"). This is the code I'm currently using and it splits on every occurrence of "\t".

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

If input = "one\ttwo\tthree\tfour", my code returns the array of:

  • one
  • two
  • three
  • four

But let's say I want to split it on every "\t" after the second "\t". So, it should return:

  • one two
  • three
  • four
like image 233
User48591 Avatar asked Apr 16 '13 10:04

User48591


People also ask

How do you split a string in a second occurrence?

a. split("-", 2) will split the string upto the second occurrence of - . a. split("-", 2)[:2] will give the first 2 elements in the list.

How do you split a string on the first occurrence of certain characters?

To split a JavaScript string only on the first occurrence of a character, call the slice() method on the string, passing it the index of the character + 1 as a parameter. The slice method will return the portion of the string after the first occurrence of the character.

How do I split a string into substring?

The split() method splits a string into an array of substrings. The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.


2 Answers

There is nothing built in.

You can use the existing Split, use Take and Skip with string.Join to rebuild the parts that you originally had.

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

An alternative is to iterate over all the characters in the string, find the index of the nth occurrence and substring before and after it (or find the next index after the nth, substring on that etc... etc... etc...).

like image 126
Oded Avatar answered Sep 27 '22 15:09

Oded


[EDIT] After re-reading the edited OP, I realise this doesn't do what is now asked. This will split on every nth target; the OP wants to split on every target AFTER the nth one.

I'll leave this here for posterity anyway.


If you were using the MoreLinq extensions you could take advantage of its Batch method.

Your code would then look like this:

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

I'd probably just use Oded's implementation, but I thought I'd post this for an alternative approach.

The implementation of Batch() looks like this:

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);
    }
}
like image 26
Matthew Watson Avatar answered Sep 27 '22 17:09

Matthew Watson