提问人:ob213 提问时间:9/25/2009 最后编辑:Mark Ruckerob213 更新时间:8/25/2017 访问量:5328
麦当劳在 C 中为 ProperCase#
mcdonalds to ProperCase in C#
答:
计算机绝对不可能神奇地知道“麦当劳”中的第一个“D”应该大写。所以,我认为有两种选择。
有人可能有一个软件或库可以为你做这件事。
除此之外,您唯一的选择是采用以下方法:首先,我会在具有“有趣”大写的单词字典中查找名称。显然,你必须自己提供这本词典,除非已经存在。其次,应用一种算法来纠正一些明显的错误,例如以 O' 开头的凯尔特人名字、Mac 和 Mc,尽管给定足够大的名字池,这样的算法无疑会有很多误报。最后,将不符合前两个条件的每个名称的首字母大写。
评论
其中最难的部分是决定大写的算法。字符串操作本身非常简单。没有完美的方法,因为案件没有“规则”。一种策略可能是一组规则,例如“将第一个字母大写......通常“和”如果前两个字母是 MC...通常”
从真实姓名词典开始,并将它们与您自己的名字进行比较以进行匹配会有所帮助。您还可以获取真实姓名字典,从中生成 Markhov 链,并将任何新名称扔给 Markhov 链以确定大小写。这是一个疯狂而复杂的解决方案。
最终的完美解决方案是使用人工来校正数据。
这样做要求你的程序能够在一定程度上解释英语。至少能够将一个字符串分解成一组单词。.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();
}
这不是一个完美的解决方案,但它可以让您大致了解大纲
您可以考虑使用搜索引擎来帮助您。提交查询,查看结果如何将名称大写。
评论
我写了以下扩展方法。随意使用它们。
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();
}
}
评论
您可以根据包含正确大小写大小写的字典(文件)检查小写/混合大小写的姓氏,然后从字典中返回“真实”值。
我快速谷歌了一下,看看是否存在,但无济于事!
评论
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
string txt = textInfo.ToTitleCase("texthere");
评论
我打算编写这样的函数,但可能不会涉及太多边缘情况......下面在带有正则表达式的伪装代码中进行匹配......
以 /\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 "
这应该能抓住大多数情况,尤其是名字......但是一个不错的通用名称大小写数据库会非常好。
这是我的解决方案。这会将名称硬编码到程序中,但只需稍加工作,您就可以在程序外部保留一个文本文件,并读取名称例外(即 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 "";
}
下一个:如何在TSQL中截断秒?
评论