1

想知道是否有比我下面的表现差的好的替代品?真正的 switch 语句具有其他非英文字符的附加部分。

请注意,我希望每行放置多个 case 语句,但 StyleCop 不喜欢它,因此会导致我们的发布版本失败。

        var retVal = String.Empty;
        switch(valToCheck)
        {
            case "é": 
            case "ê": 
            case "è": 
            case "ë":
                retVal = "e";
                break;
            case "à": 
            case "â": 
            case "ä": 
            case "å":
                retVal = "a";
                break;

            default:
                retVal = "-";
                break;
        }
4

6 回答 6

4

首先想到的是Dictionary<char,char>()
(我更喜欢 char 而不是字符串,因为您正在处理字符)

Dictionary<char,char> dict = new Dictionary<char,char>();
dict.Add('å', 'a');
......

然后你可以移除你的整个开关

char retValue;
char testValue = 'å';
if(dict.TryGetValue(testValue, out retValue) == false)
   retVal = '-';
于 2012-07-25T20:23:42.593 回答
1

好吧,从做这个转换开始。

public class CharacterSanitizer
{
    private static Dictionary<string, string> characterMappings = new Dictionary<string, string>();
    static CharacterSanitizer()
    {
        characterMappings.Add("é", "e");
        characterMappings.Add("ê", "e");
        //...
    }

    public static string mapCharacter(string input)
    {
        string output;
        if (characterMappings.TryGetValue(input, out output))
        {
            return output;
        }
        else
        {
            return input;
        }
    }
}

现在您处于字符映射是数据的一部分而不是代码的位置。我在这里对值进行了硬编码,但此时将映射存储在文件中、读入文件然后相应地填充字典已经足够简单了。这样,您不仅可以通过将 case 语句减少到一位文本文件(代码之外)来大量清理代码,而且您可以修改它而无需重新编译。

于 2012-07-25T20:24:03.590 回答
1

您可以进行小范围检查并查看ascii

假设InRange(val, min, max)检查一个数字是否,是的,在范围内..

if(InRange(System.Convert.ToInt32(valToCheck),232,235))
  return 'e';
else if(InRange(System.Convert.ToInt32(valToCheck),224,229))
  return 'a';

这使代码有点混乱,并且取决于使用的标准,但也许需要考虑一些事情。

于 2012-07-25T20:25:10.117 回答
1

这个答案假定您将 switch 语句应用于字符串,而不仅仅是单个字符(尽管这也可以)。

最好的方法似乎是这个 StackOverflow 答案中概述的方法。

我对其进行了调整以使用 LINQ:

var chars = from character in valToCheck.Normalize(NormalizationForm.FormD)
            where CharUnicodeInfo.GetUnicodeCategory(character)
                    != UnicodeCategory.NonSpacingMark
            select character;
return string.Join("", chars).Normalize(NormalizationForm.FormC);

你需要一个 using 指令System.Globalization;

样本输入:

string valToCheck = "êéÈöü";

样本输出:

eeEou
于 2012-07-25T20:35:24.413 回答
1

基于 Michael Kaplan 的 RemoveDiacritics(),您可以执行以下操作:

static char RemoveDiacritics(char c)
{
    string stFormD = c.ToString().Normalize(NormalizationForm.FormD);
    StringBuilder sb = new StringBuilder();

    for (int ich = 0; ich < stFormD.Length; ich++)
    {
        UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
        if (uc != UnicodeCategory.NonSpacingMark)
        {
            sb.Append(stFormD[ich]);
        }
    }

    return (sb.ToString()[0]);
}

switch(RemoveDiacritics(valToCheck))
{
    case 'e':
        //...
        break;
    case 'a':
        //...
        break;
        //...
}

或者,甚至可能:

retval = RemoveDiacritics(valToCheck);
于 2012-07-25T20:35:59.320 回答
0

使用Contains而不是switch.

var retVal = String.Empty;

string es = "éêèë";
if (es.Contains(valToCheck)) retVal  = "e";
//etc.
于 2012-07-25T20:26:03.687 回答