テキストをパスカルまたはキャメルケースにフォーマットするアルゴリズム
-
09-06-2019 - |
質問
この質問を使用すると、 ベースとして、一部のテキストをパスカルまたはキャメルケーシングに変更するためのアルゴリズムまたはコーディング例があります。
例えば:
mynameisfred
になる
Camel: myNameIsFred
Pascal: MyNameIsFred
解決
Perl 野郎たちがこの質問について議論しているスレッドを見つけました。 http://www.perlmonks.org/?node_id=336331.
これが質問に対する答えになっていないことを望みますが、これは非常に制限のないアルゴリズムであり、多くの「ミス」も発生する可能性があるという点で少し問題があると思います。ヒット曲として。たとえば、次のように入力したとします。
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() 関数を適切な大文字小文字のアルゴリズムに置き換えることもできます。
上記のアルゴリズムの C# 実装は次のとおりです (テスト ハーネスを備えた完全なコンソール プログラム)。
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」は単なる文字の配列であり、これを my Name Is Fred に分割することは、これらの各文字の結合が何を意味するかを理解することを意味します。
入力が何らかの方法で分離されていれば、それを簡単に行うことができます。「私の名前はフレッドです」または「私の名前はフレッドです」。