Splitting a filename

.net, c#, silverlight-4.0, split

Solution

You can specify the maximum number of substrings to return:

var strFileTokens = filename.Split(new[] { '-' }, 4, StringSplitOptions.None);

This will avoid splitting `2wd28830-841c-4d30-95fd-a57a7aege412.zip` into additional "pieces".

(Also, you can drop `StringSplitOptions.None` since that's the default.)

Internally, it creates an array of substrings inside a loop, and it only loops the number of times you specify (or the maximum number of delimiters available in your string, whichever is less).

for (int i = 0; i < numActualReplaces && currIndex < Length; i++)
{
    splitStrings[arrIndex++] = Substring(currIndex, sepList[i] - currIndex );
    currIndex = sepList[i] + ((lengthList == null) ? 1 : lengthList[i]); 
}

The variable `numActualReplaces` is the minimum of either the count you specify, or the number of actual delimiters present in your string. (That way, if you specify a larger number like 30, but you only have 7 hyphens in the string, you won't get an exception. Actually, when you don't specify a number at all, it's actually using `Int32.MaxValue` without you even realizing it.)

You updated your question to say you're using Silverlight, which doesn't have he overloads with `Count`. That's really annoying, because under the hood the `string` class still supports it. They just didn't provide a way to pass in your own value. It uses a hard-coded `int.MaxValue`.

You could create your own method to bring back the desired functionality. I haven't tested this extension method out for all edge-cases, but it does work with your string.

public static class StringSplitExtension
{
    public static string[] SplitByCount(this string input, char[] separator, int count)
    {
        if (count < 0)
            throw new ArgumentOutOfRangeException("count");

        if (count == 0)
            return new string[0];

        var numberOfSeparators = input.Count(separator.Contains);

        var numActualReplaces = Math.Min(count, numberOfSeparators + 1);

        var splitString = new string[numActualReplaces];

        var index = -1;
        for (var i = 1; i <= numActualReplaces; i++)
        {
            var nextIndex = input.IndexOfAny(separator, index + 1);
            if (nextIndex == -1 || i == numActualReplaces)
                splitString[i - 1] = input.Substring(index + 1);
            else
                splitString[i - 1] = input.Substring(index + 1, nextIndex - index - 1);
            index = nextIndex;
        }

        return splitString;
    }
}

Make sure it's somewhere accessible to your UserControl, then call it like this:

var strFileTokens = filename.SplitByCount(new[] { '-' }, 4)

Problem

I've a filename: ``` NewReport-20140423_17255375-BSIQ-2wd28830-841c-4d30-95fd-a57a7aege412.zip ``` How can i split the above filename to 4 string groups. ``` NewReport 20140423_17255375 BSIQ 2wd28830-841c-4d30-95fd-a57a7aege412.zip ``` I tried: ``` string[] strFileTokens = filename.Split(new char[]{'-'} , StringSplitOptions.None); ``` but i'm not getting the above required four strings

Original source