如何在C#中将名称转换为正确的大小写?
我有一份我想要证明的名单。
例如:麦当劳的麦当劳或奥布莱恩的奥布莱恩。
答案 0 :(得分:9)
您可以考虑使用搜索引擎来帮助您。提交查询并查看结果如何将名称大写。
答案 1 :(得分:7)
计算机绝对没有办法神奇地知道“麦当劳”中的第一个“D”应该大写。所以,我认为有两种选择。
有人可能会有一个软件或图书馆为你做这件事。
除此之外,您唯一的选择是采取以下方法:首先,我会在一个词汇词典中查找具有“有趣”大写字母的词典。显然你必须自己提供这本词典,除非已经存在。其次,应用一种算法来纠正一些明显的算法,比如以O'和Mac和Mc开头的凯尔特人的名字,虽然给出了足够多的名字,这样的算法无疑会产生很多误报。最后,将每个不符合前两个标准的名字的第一个字母大写。
答案 2 :(得分:6)
我写了以下扩展方法。随意使用它们。
public static class StringExtensions
{
public static string ToProperCase( this string original )
{
if( original.IsNullOrEmpty() )
return original;
string result = _properNameRx.Replace( original.ToLower( CultureInfo.CurrentCulture ), HandleWord );
return result;
}
public static string WordToProperCase( this string word )
{
if( word.IsNullOrEmpty() )
return word;
if( word.Length > 1 )
return Char.ToUpper( word[0], CultureInfo.CurrentCulture ) + word.Substring( 1 );
return word.ToUpper( CultureInfo.CurrentCulture );
}
private static readonly Regex _properNameRx = new Regex( @"\b(\w+)\b" );
private static readonly string[] _prefixes = { "mc" };
private static string HandleWord( Match m )
{
string word = m.Groups[1].Value;
foreach( string prefix in _prefixes )
{
if( word.StartsWith( prefix, StringComparison.CurrentCultureIgnoreCase ) )
return prefix.WordToProperCase() + word.Substring( prefix.Length ).WordToProperCase();
}
return word.WordToProperCase();
}
}
答案 3 :(得分:2)
这是一个有趣的问题。我不认为有一个“开箱即用”的解决方案。
我已经为以下文章添加了书签,这篇文章可能与您想要的内容相近:
Lost and Found Identity Proper Case Format Provider (IFormatProvider implementation)
我没有尝试过代码,这个解决方案非常需要手动处理所有情况。但这是一个开始,也许你会发现它很有用。
答案 4 :(得分:1)
这很难实现决定资本化的算法。字符串操作本身非常简单。没有完美的方法,因为案件没有“规则”。一种策略可能是一组规则,例如“大写第一个字母......通常”和“如果前两个字母是mc,则将第三个字母大写...通常”
从真实姓名字典开始,并将它们与您自己的姓名进行比较,这将有所帮助。您还可以获取实名字典,从中生成Markhov链,并在Markhov链上抛出任何新名称以确定大小写。这是一个疯狂而复杂的解决方案。
最终的完美解决方案是使用人来纠正数据。
答案 5 :(得分:0)
这样做需要您的程序能够在一定程度上解释英语。至少能够将一个字符串分解成一组单词。 .Net Framework中没有内置API可以实现这一目标。
但是,如果有,您可以使用以下代码。
public string ProperCase(string str, Func<string,bool> isWord) {
var word = new StringBuilder();
var cur = new StringBuilder();
for ( var i = 0; i < str.Length; i++ ) {
cur.Append(cur.Length == 0 ? Char.ToUpper(str[i]) : str[i]));
if ( isWord(cur.ToString()) {
word.Append(cur.ToString());
cur.Length = 0;
}
}
if ( cur.Length > 0 ) {
word.Append(cur);
}
return word.ToString();
}
这不是一个完美的解决方案,但它可以让你大致了解大纲
答案 6 :(得分:0)
您可以针对包含正确内容的字典(文件)检查较低/混合大小写的姓氏,然后从字典中返回“真实”值。
我有一个快速谷歌,看看是否存在,但无济于事!
答案 7 :(得分:0)
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
string txt = textInfo.ToTitleCase("texthere");
答案 8 :(得分:0)
我打算编写这样一个函数,但可能不会涉及太多边缘情况......下面是psuedo-code,正则表达式匹配......
以/ \ b [A-Z] + \ b /作为集合匹配开始,因此每个字母序列与单词边界对齐,匹配为一组。
if the string is all uppercase...
lower-case the string
upper-case the first letter
do the following beginning of string replacements
Vanb -> VanB
Vanh -> VanH
Mc? -> Mc? (uppercase wildcard character)
Mac[^kh] -> Mac? (uppercase wildcard match)
使用替换的全名字符串与其他替换集匹配,如...
"De La " -> "de la "
这应该可以捕获大多数特殊名称的情况......但是一个很好的通用名称套管数据库会非常好。
答案 9 :(得分:0)
这是我的解决方案。这会将名称硬编码到程序中,但只需要做一些工作就可以将文本文件保存在程序之外并读取名称例外(即Van,Mc,Mac)并循环浏览它们。
public static String toProperName(String name)
{
if (name != null)
{
if (name.Length >= 2 && name.ToLower().Substring(0, 2) == "mc") // Changes mcdonald to "McDonald"
return "Mc" + Regex.Replace(name.ToLower().Substring(2), @"\b[a-z]", m => m.Value.ToUpper());
if (name.Length >= 3 && name.ToLower().Substring(0, 3) == "van") // Changes vanwinkle to "VanWinkle"
return "Van" + Regex.Replace(name.ToLower().Substring(3), @"\b[a-z]", m => m.Value.ToUpper());
return Regex.Replace(name.ToLower(), @"\b[a-z]", m => m.Value.ToUpper()); // Changes to title case but also fixes
// appostrophes like O'HARE or o'hare to O'Hare
}
return "";
}