XSLT isn't the best language for string processing, but it (XPath actually) has a very handy pair of substring functions: substring-before() and substring-after(). I used to write XSLT a lot and always missed them in C# or Java. Yes, C# and Java have indexOf() and regex, but indexOf() is too low-level and so makes code more complicated than it needs to be, while regular expressions is overkill for such simple, but very common operation.
Anyway, as an exercise in C# 3.0 I built these string extension functions following XPath 1.0 semantics for the substring-before() and substring-after(). Now I can have clean nice
arg.SubstringAfter(":")
instead of ugly
arg.Substring(arg.IndexOf(":")+1)
and shorter and more natural than
StringUtils.SubstringAfter(arg, ":")
Anyway, here is the code:
using System;
using System.Linq;
using System.Globalization;
namespace XmlLab.Extensions
{
public static class StringExtensions
{
public static string SubstringAfter(this string source, string value)
{
if (string.IsNullOrEmpty(value))
{
return source;
}
CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
int index = compareInfo.IndexOf(source, value, CompareOptions.Ordinal);
if (index < 0)
{
//No such substring
return string.Empty;
}
return source.Substring(index + value.Length);
}
public static string SubstringBefore(this string source, string value)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
int index = compareInfo.IndexOf(source, value, CompareOptions.Ordinal);
if (index < 0)
{
//No such substring
return string.Empty;
}
return source.Substring(0, index);
}
}
}

Update: Dimitre posts translate() inplementation, check it out: http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!353.entry