在string比较中忽略重音字母

我需要比较C#中的两个string,并将重音字母与非重音字母相同。 例如:

string s1 = "hello"; string s2 = "héllo"; s1.Equals(s2, StringComparison.InvariantCultureIgnoreCase); s1.Equals(s2, StringComparison.OrdinalIgnoreCase); 

这两个string需要相同(就我的应用程序而言),但是这两个语句的计算结果都是错误的。 在C#中有没有办法做到这一点?

编辑2012-01-20:哦,小子! 解决scheme非常简单,几乎永远在框架中。 正如knightpfhor指出的那样 :

 string.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace); 

这是一个从string中删除变音符号的函数:

 static string RemoveDiacritics(string text) { string formD = text.Normalize(NormalizationForm.FormD); StringBuilder sb = new StringBuilder(); foreach (char ch in formD) { UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch); if (uc != UnicodeCategory.NonSpacingMark) { sb.Append(ch); } } return sb.ToString().Normalize(NormalizationForm.FormC); } 

MichKap的博客上的更多细节( RIP … )。

原则是,它是'é'变成连续的两个字符'e',急剧。 然后它遍历字符并跳过变音符号。

“héllo”变成“he <acute> llo”,然后变成“hello”。

 Debug.Assert("hello"==RemoveDiacritics("héllo")); 

注意:这是一个更紧凑的相同function的.NET4 +友好版本:

 static string RemoveDiacritics(string text) { return string.Concat( text.Normalize(NormalizationForm.FormD) .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch)!= UnicodeCategory.NonSpacingMark) ).Normalize(NormalizationForm.FormC); } 

如果你不需要转换string,你只是想检查平等,你可以使用

 string s1 = "hello"; string s2 = "héllo"; if (String.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace) == 0) { // both strings are equal } 

或者如果你想比较也是不区分大小写的

 string s1 = "HEllO"; string s2 = "héLLo"; if (String.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0) { // both strings are equal } 

以下方法CompareIgnoreAccents(...)适用于您的示例数据。 这里是我得到我的背景资料的文章: http : //www.codeproject.com/KB/cs/EncodingAccents.aspx

 private static bool CompareIgnoreAccents(string s1, string s2) { return string.Compare( RemoveAccents(s1), RemoveAccents(s2), StringComparison.InvariantCultureIgnoreCase) == 0; } private static string RemoveAccents(string s) { Encoding destEncoding = Encoding.GetEncoding("iso-8859-8"); return destEncoding.GetString( Encoding.Convert(Encoding.UTF8, destEncoding, Encoding.UTF8.GetBytes(s))); } 

我认为扩展方法会更好:

 public static string RemoveAccents(this string s) { Encoding destEncoding = Encoding.GetEncoding("iso-8859-8"); return destEncoding.GetString( Encoding.Convert(Encoding.UTF8, destEncoding, Encoding.UTF8.GetBytes(s))); } 

那么使用会是这样的:

 if(string.Compare(s1.RemoveAccents(), s2.RemoveAccents(), true) == 0) { ... 

我不得不做类似的事情,但有一个StartsWith方法。 这是从@Serge – appTranslator派生的一个简单的解决scheme。

这是一个扩展方法:

  public static bool StartsWith(this string str, string value, CultureInfo culture, CompareOptions options) { if (str.Length >= value.Length) return string.Compare(str.Substring(0, value.Length), value, culture, options) == 0; else return false; } 

而一个衬里的怪胎;)

  public static bool StartsWith(this string str, string value, CultureInfo culture, CompareOptions options) { return str.Length >= value.Length && string.Compare(str.Substring(0, value.Length), value, culture, options) == 0; } 

强调不敏感和大小写不敏感的启动可以这样调用

 value.ToString().StartsWith(str, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) 

一个更简单的方法来删除口音:

  Dim source As String = "áéíóúç" Dim result As String Dim bytes As Byte() = Encoding.GetEncoding("Cyrillic").GetBytes(source) result = Encoding.ASCII.GetString(bytes) 

在String.Compare方法上试试这个重载。

String.Compare方法(String,String,Boolean,CultureInfo)

它根据比较操作(包括cultureinfo)生成一个int值。 该页面中的示例比较了en-US和en-CZ中的“更改”。 en-CZ中的CH是单个“字母”。

例如从链接

 using System; using System.Globalization; class Sample { public static void Main() { String str1 = "change"; String str2 = "dollar"; String relation = null; relation = symbol( String.Compare(str1, str2, false, new CultureInfo("en-US")) ); Console.WriteLine("For en-US: {0} {1} {2}", str1, relation, str2); relation = symbol( String.Compare(str1, str2, false, new CultureInfo("cs-CZ")) ); Console.WriteLine("For cs-CZ: {0} {1} {2}", str1, relation, str2); } private static String symbol(int r) { String s = "="; if (r < 0) s = "<"; else if (r > 0) s = ">"; return s; } } /* This example produces the following results. For en-US: change < dollar For cs-CZ: change > dollar */ 

因此对于重音语言,您将需要获得文化,然后根据testingstring。

http://msdn.microsoft.com/en-us/library/hyxc48dt.aspx