使用这个问题作为基础,有一个算法或编码示例可以将一些文本更改为 Pascal 或 Camel 大小写。
例如:
mynameisfred
变成
Camel: myNameIsFred
Pascal: MyNameIsFred
使用这个问题作为基础,有一个算法或编码示例可以将一些文本更改为 Pascal 或 Camel 大小写。
例如:
mynameisfred
变成
Camel: myNameIsFred
Pascal: MyNameIsFred
我在http://www.perlmonks.org/?node_id=336331上找到了一个线程,其中有一群 Perl 人在争论这个问题。
我希望这不是对这个问题的太多非回答,但我会说你有一点问题,因为这将是一个非常开放的算法,也可能有很多“未命中”作为命中。例如,假设您输入:-
camelCase("hithisisatest");
输出可能是:-
"hiThisIsATest"
或者:-
"hitHisIsATest"
算法不可能知道更喜欢哪个。您可以添加一些额外的代码来指定您更喜欢更常用的单词,但会再次出现遗漏(Peter Norvig 在http://norvig.com/spell-correct.html上写了一个非常小的拼写纠正器,这可能有助于算法- 明智的,如果 C# 是你的语言,我写了一个C# 实现)。
我同意 Mark 的观点,并说你最好有一个算法来接受分隔输入,即 this_is_a_test 并将其转换。这很容易实现,即在伪代码中:-
SetPhraseCase(phrase, CamelOrPascal):
if no delimiters
if camelCase
return lowerFirstLetter(phrase)
else
return capitaliseFirstLetter(phrase)
words = splitOnDelimiter(phrase)
if camelCase
ret = lowerFirstLetter(first word)
else
ret = capitaliseFirstLetter(first word)
for i in 2 to len(words): ret += capitaliseFirstLetter(words[i])
return ret
capitaliseFirstLetter(word):
if len(word) <= 1 return upper(word)
return upper(word[0]) + word[1..len(word)]
lowerFirstLetter(word):
if len(word) <= 1 return lower(word)
return lower(word[0]) + word[1..len(word)]
如果您愿意,也可以用适当的大小写算法替换我的 capitaliseFirstLetter() 函数。
上述算法的 AC# 实现如下(带有测试工具的完整控制台程序):-
using System;
class Program {
static void Main(string[] args) {
var caseAlgorithm = new CaseAlgorithm('_');
while (true) {
string input = Console.ReadLine();
if (string.IsNullOrEmpty(input)) return;
Console.WriteLine("Input '{0}' in camel case: '{1}', pascal case: '{2}'",
input,
caseAlgorithm.SetPhraseCase(input, CaseAlgorithm.CaseMode.CamelCase),
caseAlgorithm.SetPhraseCase(input, CaseAlgorithm.CaseMode.PascalCase));
}
}
}
public class CaseAlgorithm {
public enum CaseMode { PascalCase, CamelCase }
private char delimiterChar;
public CaseAlgorithm(char inDelimiterChar) {
delimiterChar = inDelimiterChar;
}
public string SetPhraseCase(string phrase, CaseMode caseMode) {
// You might want to do some sanity checks here like making sure
// there's no invalid characters, etc.
if (string.IsNullOrEmpty(phrase)) return phrase;
// .Split() will simply return a string[] of size 1 if no delimiter present so
// no need to explicitly check this.
var words = phrase.Split(delimiterChar);
// Set first word accordingly.
string ret = setWordCase(words[0], caseMode);
// If there are other words, set them all to pascal case.
if (words.Length > 1) {
for (int i = 1; i < words.Length; ++i)
ret += setWordCase(words[i], CaseMode.PascalCase);
}
return ret;
}
private string setWordCase(string word, CaseMode caseMode) {
switch (caseMode) {
case CaseMode.CamelCase:
return lowerFirstLetter(word);
case CaseMode.PascalCase:
return capitaliseFirstLetter(word);
default:
throw new NotImplementedException(
string.Format("Case mode '{0}' is not recognised.", caseMode.ToString()));
}
}
private string lowerFirstLetter(string word) {
return char.ToLower(word[0]) + word.Substring(1);
}
private string capitaliseFirstLetter(string word) {
return char.ToUpper(word[0]) + word.Substring(1);
}
}
做到这一点的唯一方法是通过字典运行单词的每个部分。
“mynameisfred”只是一个字符数组,将其拆分为我的名字是 Fred 意味着了解每个字符的连接意味着什么。
如果您的输入以某种方式分开,您可以轻松地做到这一点,例如“我的名字是弗雷德”或“my_name_is_fred”。