How to split a string while ignoring the case of the delimiter?

Viewed 23685

I need to split a string let's say "asdf aA asdfget aa uoiu AA" split using "aa" ignoring the case. to

"asdf "
"asdfget "
"uoiu "
10 Answers

Use My Method to Split

public static string[] Split(this string s,string word,StringComparison stringComparison)
    {
        List<string> tmp = new List<string>();
        int wordSt;
        s.IndexOf(word, 0, stringComparison);
        while(s.IndexOf(word, 0, stringComparison) > -1)
        {
            wordSt = s.IndexOf(word, 0, stringComparison);
            tmp.Add(s.Substring(0, wordSt));
            s = s.Substring(wordSt + word.Length);
        }
        tmp.Add(s);
        return tmp.ToArray();
    }

I have had good success with this extension method I wrote that uses .replace() to find and fix the casing.

You call it as follows:

var result = source.Split(prefix, StringComparison.InvariantCultureIgnoreCase);

The extension method is defined as follows.

public static string[] Split(this string source, string separator, 
    StringComparison comparison = StringComparison.CurrentCulture, 
    StringSplitOptions splitOptions = StringSplitOptions.None)
{
    if (source is null || separator is null)
        return null;

    // Pass-through the default case.
    if (comparison == StringComparison.CurrentCulture)
        return source.Split(new string[] { separator }, splitOptions);
    
    // Use Replace to deal with the non-default comparison options.
    return source
        .Replace(separator, separator, comparison)
        .Split(new string[] { separator }, splitOptions);
}

NOTE: This method deals with my default case where I am usually passing a single string separator.

Dim arr As String() = Strings.Split("asdf aA asdfget aa uoiu AA", 
                                    "aa" ,, CompareMethod.Text)

CompareMethod.Text ignores case.

Building on the answer from @Noldorin i made this extension method.

It takes in more than one seperator string, and mimics the behavior of string.Split(..) if you supply several seperator strings. It has invariant ('culture-unspecific') culture and ignores cases of course.

/// <summary>
/// <see cref="string.Split(char[])"/> has no option to ignore casing.
/// This functions mimics <see cref="string.Split(char[])"/> but also ignores casing.
/// When called with <see cref="StringSplitOptions.RemoveEmptyEntries"/> <see cref="string.IsNullOrWhiteSpace(string)"/> is used to filter 'empty' entries.
/// </summary>
/// <param name="input">String to split</param>
/// <param name="separators">Array of separators</param>
/// <param name="options">Additional options</param>
/// <returns></returns>
public static IEnumerable<string> SplitInvariantIgnoreCase(this string input, string[] separators, StringSplitOptions options)
{
    if (separators == null) throw new ArgumentNullException(nameof(separators));
    if (separators.Length <= 0) throw new ArgumentException("Value cannot be an empty collection.", nameof(separators));
    if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(input));

    // Build a regex pattern of all the separators this looks like aa|bb|cc
    // The Pipe character '|' means alternative.
    var regexPattern = string.Join("|", separators);

    var regexSplitResult = Regex.Split(input, regexPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

    // NOTE To be honest - i don't know the exact behaviour of Regex.Split when it comes to empty entries.
    //      Therefore i doubt that filtering null values even matters - however for consistency i decided to code it in anyways.
    return options.HasFlag(StringSplitOptions.RemoveEmptyEntries) ? 
        regexSplitResult.Where(c => !string.IsNullOrWhiteSpace(c)) 
        : regexSplitResult;
}
Related