在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。