File name comparer

public class FileNameComparer : IComparer<string>
{
    public enum StringDirection
    {
        Normal,
        Reversed
    }

    static int GetCommonLength(string a, int i, string b, int j, StringDirection dir = StringDirection.Normal)
    {
        if (i < 0 || i >= a.Length || j < 0 || j >= b.Length) {
            throw new IndexOutOfRangeException();
        }

        int n = 0;
        while (i < a.Length && j < b.Length) {
            var p1 = dir == StringDirection.Normal ? i : a.Length - i - 1;
            var p2 = dir == StringDirection.Normal ? j : b.Length - j - 1;
            if (a[p1] != b[p2]) break;
            i++;
            j++;
            n++;
        }
        return n;
    }

    public int Compare(string a, string b)
    {
        var lenA = a.Length;
        var lenB = b.Length;
        Regex regex = new Regex(@"^(\w+[\.\-]{0,})+$");

        if (lenA > 0 && lenB > 0) {
            var i = GetCommonLength(a, 0, b, 0);
            var j = GetCommonLength(a, 0, b, 0, StringDirection.Reversed);

            if (i > 0) {
                var dA = (i + j > lenA) ? string.Empty : a.Substring(i, lenA - i - j).Trim();
                var dB = (i + j > lenB) ? string.Empty : b.Substring(i, lenB - i - j).Trim();
                if (regex.IsMatch(dA) && regex.IsMatch(dB)) {
                    var r2 = new Regex(@"[A-Za-z0-9]+");
                    var m1 = r2.Matches(dA);
                    var m2 = r2.Matches(dB);
                    for (int k = 0; k < Math.Min(m1.Count, m2.Count); k++) {
                        var len = m1[k].Length - m2[k].Length;
                        if (len != 0) return len > 0 ? 1 : -1;
                        var ret = string.Compare(m1[k].Value, m2[k].Value);
                        if (ret != 0) return ret;
                    }
                }
                return dA.CompareTo(dB);
            }
        }
        return a.CompareTo(b);
    }
}