IndexOf与自定义StringComparer

为什么String.IndexOf(String, StringComparison)需要StringComparison而不允许更通用的StringComparer ,甚至不允许IComparerIEqualityComparer

我创建了一个自定义的StringComparer来与几个字典一起使用,我想在项目的其他部分使用它但是如果没有大量的扩展方法,我就找不到一个好方法,如果那些甚至可以工作的话。

这是我制作的比较器。 它大致基于此建议: 使用字符串实现自定义IComparer

另请注意,ModifyString是WIP。 我期望在那里添加更多东西,基于我正在比较的输入。 我也知道它很贵,但我只是在寻找解决方案ATM,而不是性能。

 public class CustomComparer : StringComparer { public override int Compare(string x, string y) { return StringComparer.Ordinal.Compare(ModifyString(x), ModifyString(y)); } public override bool Equals(string x, string y) { if (ModifyString(x).Equals(ModifyString(y))) return true; else return false; } public override int GetHashCode(string obj) { if (obj == null) return 0; else return ModifyString(obj).GetHashCode(); } private string ModifyString(string s) { //I know this code is expensive/naaive, your suggestions are welcome. s = s.ToLowerInvariant(); s = s.Trim(); s = Regex.Replace(s, @"\s+", " ");//replaces all whitespace characters with a single space. return s; } } 

使用IEnumerable的方便扩展似乎它应该已经,你可以编写一个String扩展来使用StringComparer 。 正如注释中所建议的那样,所有可能的子串长度都在每个位置进行测试,因为不能对自定义StringComparer做出任何假设。

 public static class IEnumerableExt { public static T FirstOrDefault(this IEnumerable src, Func testFn, T defval) => src.Where(aT => testFn(aT)).DefaultIfEmpty(defval).First(); } public static class StringExt { public static int IndexOf(this string source, string match, StringComparer sc) { return Enumerable.Range(0, source.Length) // for each position in the string .FirstOrDefault(i => // find the first position where either // match is Equals at this position for length of match (or to end of string) or sc.Equals(source.Substring(i, Math.Min(match.Length, source.Length-i)), match) || // match is Equals to on of the substrings beginning at this position Enumerable.Range(1, source.Length-i-1).Any(ml => sc.Equals(source.Substring(i, ml), match)), -1 // else return -1 if no position matches ); } }