想知道是否有更好的替代方案,表现不比我下面的更糟糕?真正的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;
}
答案 0 :(得分: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 = '-';
答案 1 :(得分: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语句减少到一位文本文件(代码之外)来大量清理代码,而且可以修改它而无需重新编译。
答案 2 :(得分: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';
这使得代码有点混乱,并且取决于所使用的标准,但也许需要考虑。
答案 3 :(得分:1)
这个答案假设您要将该switch语句应用于字符串,而不仅仅是单个字符(尽管这也可以)。
最好的方法似乎是this StackOverflow answer中列出的方法。
我改编它使用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);
您需要System.Globalization;
示例输入:
string valToCheck = "êéÈöü";
示例输出:
eeEou
答案 4 :(得分: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);
答案 5 :(得分:0)
使用Contains
代替switch
。
var retVal = String.Empty;
string es = "éêèë";
if (es.Contains(valToCheck)) retVal = "e";
//etc.