2008-12-11 80 views
112

我需要比較C#中的2個字符串,並將重音字母與非重音字母相同。例如:忽略字符串比較中的重音字母

string s1 = "hello"; 
string s2 = "héllo"; 

s1.Equals(s2, StringComparison.InvariantCultureIgnoreCase); 
s1.Equals(s2, StringComparison.OrdinalIgnoreCase); 

這兩個字符串必須是相同的(至於我的應用程序而言),但是這兩個語句的計算結果爲假。 C#中有沒有辦法做到這一點?

回答

211

編輯2012-01-20:哦,小子!解決方案非常簡單,幾乎永遠在框架中。 As pointed out by knightpfhor

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

下面是從一個字符串條變音符號的功能:

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); 
} 

更多細節on MichKap's blogRIP...)。

原理是,它將'é'變成2個連續字符'e',急劇。 然後它遍歷字符並跳過變音符號。

「héllo」變成「他<銳利> llo」,其反過來變成「你好」。

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

注:這裏有一個更緊湊。同樣功能的NET4 +友好界面:

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

在String.Compare方法上試試這個重載。

String.Compare方法(字符串,字符串,布爾值的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 
*/ 

爲此重音符號的語言

例如,你將需要獲得文化測試,然後根據該字符串。

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

+0

這是比直接比較字符串更好的方法,但它仍然考慮基本字母及其重音版本*不同*。因此,它不回答原來的問題,它希望忽略重音。 – 2013-05-15 14:43:49

6

下面的方法對你的榜樣的數據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) { 
    ... 
+1

這使重音字母'?' – onmyway133 2012-11-07 04:51:20

+3

這是一個破壞性的比較,例如,ā和ē將被視爲平等。你丟失了0xFF以上的任何字符,並且不能保證這些字符串是相同的 - 忽略 - 重音。 – Abel 2013-05-07 15:18:02

+0

你也會失去像ñ一樣的東西。如果你問我,不是一個解決方案。 – 2016-02-02 08:45:36

106

如果您不需要字符串轉換,你只是想檢查平等,你可以使用

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 
} 
0

我不得不做類似的,但有StartsWith方法的東西。這是一個從@Serge - appTranslator派生而來的簡單解決方案。

下面是一個擴展方法:

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; 
    } 

口音incensitive和殼體incensitive startsWith可以稱爲像這樣

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

甲更簡單的刪除口音的方法:

Dim source As String = "áéíóúç" 
    Dim result As String 

    Dim bytes As Byte() = Encoding.GetEncoding("Cyrillic").GetBytes(source) 
    result = Encoding.ASCII.GetString(bytes) 
相關問題