Ant
no notes

Find - a string extension

This is a lovely bit of recursion which will find the first occurrence of any number of sub-strings in a string, and allows you to add a number of "protection" delimiters so that strings inside will not be found - if you see what I mean...

delimiters = new FindDelimiters { { "'", "'" } };
Assert.AreEqual(28, 
    "do not find 'x' but do find x".Find(delimiters, "x"));

This is useful for parsing things like html/xml attributes

/// <summary>
///   <para>Find the first index of any of the passed string values</para>
/// </summary>
/// <param name="text">Text to search</param>
/// <param name="startIndex">Staring index</param>
/// <param name="delimiters">Protected delimiters</param>
/// <param name="stringComparison">String Comparison</param>
/// <param name="values">Values to find, finds first</param>
/// <returns>FindResult, which is an implicit int, -1 = not found</returns>
public static FindResult Find(
        this string text, int startIndex, FindDelimiters delimiters,
        StringComparison stringComparison, params string[] values) {
    if (text == null || values == null
        || startIndex < 0 || startIndex > text.Length) return null;
    var found = (from v in values
                 let i = text.IndexOf(v, startIndex, stringComparison)
                 orderby i
                 where i != -1
                 select new FindResult {Found = v, Index = i})
        .FirstOrDefault();

    if (found != null
        && delimiters != null
        && delimiters.Count > 0) {
        // check for delimiter open before the found value
        var open = (from d in delimiters
                    let iOpen = text
                        .IndexOf(d.Key, startIndex, stringComparison)
                    orderby iOpen
                    where iOpen != -1 && iOpen < found.Index
                    select new {Delimiter = d, Index = iOpen})
            .FirstOrDefault();

        if (open != null) {
            // check for valid close on found delimiter
            var close = Find(text,
                open.Index + 1, stringComparison, open.Delimiter.Value);
            if (close != null)
                // find after delimiter closed
                return Find(text,
                    close.Index + 1, delimiters, stringComparison, values);
        }
    }

    return found;
}
	
Supporting classes
/// <summary>
///   <para>Result of a call to find</para>
///   <para>Implicit conversion to int,
///         if null (not found) will return -1</para>
/// </summary>
public class FindResult {
    public string Found { get; internal set; }
    public int Index { get; internal set; }

    public static implicit operator int(FindResult r) {
        return r == null ? -1 : r.Index;
    }
}

/// <summary>
///   <para>Strings that can wrap another string, 
///         for example a quote</para>
/// </summary>
public class FindDelimiters:Dictionary<string,string> {}
		

Tags C# Strings

Post a Note

(required)

(required never shown)

On Twitter Follow MrAntix on Twitter

15/05/2012
WindowsAzure
Announcing the MEET Windows Azure Event! Streamed online June 7th. Register at http://t.co/bObzTAuL  #MEETAzure #WindowsAzure

10/05/2012
kevinwhinnery
Comparing Titanium and PhoneGap - A common question I get asked at developer events and conferences is how... http://t.co/Zq2eND6B

09/05/2012
brianleroux
PhoneGap goals and philosophy: http://t.co/wkq8wI2T

just now
ChaseDiane
encrypting phonegap android by joseesfera: currently being developed for PhoneGap app, we need to encrypt the co... http://t.co/qCSGs9iX

just now
rgonv
#Tech Post: Bing Search API now available on Windows Azure Marketplace: The Bing Search API is now available on ... http://t.co/iBvXOjbC