我可以获得用于与CompareOptions进行比较的结果字符串吗?

时间:2014-04-16 19:18:58

标签: c# .net string icomparer

我有自定义IComparer<string>我用它来比较忽略其大小写的字符串和这样的符号:

public class LiberalStringComparer : IComparer<string>
    {

        private readonly CompareInfo _compareInfo = CultureInfo.InvariantCulture.CompareInfo;
        private const CompareOptions COMPARE_OPTIONS = CompareOptions.IgnoreSymbols | CompareOptions.OrdinalIgnoreCase;


        public int Compare(string x, string y)
        {
            if (x == null) return -1;
            if (y == null) return 1;
            return this._compareInfo.Compare(x, y, COMPARE_OPTIONS);
        }
    }

我可以获得最终用于比较的输出字符串吗?

我的最终目标是生成和IEqualityComparer<string>,它以与此比较器相同的方式忽略符号和套管。

我可以编写正则表达式,但不能保证我的正则表达式将使用与内置比较选项相同的逻辑。

2 个答案:

答案 0 :(得分:1)

这里有一个非常有趣的问题。 Internaly CompareInfo.Compare使用InternalCompareString方法从COMNlsInfo::InternalCompareString引入clr.dll

// Compare a string using the native API calls -- COMNlsInfo::InternalCompareString   
...
private static extern int InternalCompareString(IntPtr handle, 
             IntPtr handleOrigin, String localeName, String string1, int offset1, 
             int length1, String string2, int offset2, int length2, int flags);

换句话说,由于您无法确定内置函数的逻辑,也许您应该自己编写并在IEqualityComparerIComparer实现中重用它。

答案 1 :(得分:1)

可能没有这样的“输出字符串”。我会以这种方式实施您的Equals

return liberalStringComparer.Compare(x, y) == 0;

GetHashCode更复杂。

一些方法:

  1. 使用像return 0;这样糟糕的实现(这意味着您必须始终运行Compare才能知道它们是否相同。)
  2. 由于您的比较相对简单(不变文化,序数忽略大小写比较),您应该能够创建通常有效的哈希。但是,如果没有对Unicode和测试的广泛研究,我建议您不要认为这适用于来自任何文化的任何有效Unicode字符串。

    在伪代码中:

    public int GetHashCode(string value)
    {
        // for each index in value
        if (!char.IsSymbol(value, i))
            // add value[i].ToUpperInvariant() to the hash using an algorithm
            // like http://stackoverflow.com/a/263416/781792
    }
    
  3. 删除char.IsSymbol true所有位置,然后在其上使用StringComparer.InvariantCulture.GetHashCode来形成字符串。
  4. CompareInfo.GetSortKey的哈希码应该是合适的值。

    public int GetHashCode(string value)
    {
        return _compareInfo.GetSortKey(value, COMPARE_OPTIONS).GetHashCode();
    }