Алгоритм форматирования текста в оболочку Pascal или camel

StackOverflow https://stackoverflow.com/questions/32241

Вопрос

Используя этот вопрос в качестве основы есть алгоритм или пример кодирования для изменения некоторого текста на Pascal или Camel case.

Например:

mynameisfred

становится

Camel: myNameIsFred
Pascal: MyNameIsFred
Это было полезно?

Решение

Я нашел ветку с группой ребят из Perl, спорящих по этому вопросу на http://www.perlmonks.org/?node_id=336331.

Я надеюсь, что это не слишком большой отказ от ответа на вопрос, но я бы сказал, что у вас есть небольшая проблема в том, что это был бы очень открытый алгоритм, который мог бы иметь много "промахов", а также попаданий.Например, допустим, вы ввели:-

camelCase("hithisisatest");

Результатом может быть:-

"hiThisIsATest"

Или:-

"hitHisIsATest"

Алгоритм никак не мог бы знать, что предпочесть.Вы могли бы добавить дополнительный код, чтобы указать, что вы предпочитаете более распространенные слова, но снова будут возникать промахи (Питер Норвиг написал очень маленький корректор орфографии по адресу http://norvig.com/spell-correct.html который мог бы с точки зрения алгоритма помощи, я написал Реализация на C # если C # - ваш язык).

Я бы согласился с Марком и сказал, что вам было бы лучше иметь алгоритм, который принимает входные данные с разделителями, т.е.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" - это просто набор символов, разбить его на "меня зовут Фред" означает понять, что означает объединение каждого из этих символов.

Вы могли бы сделать это легко, если бы ваш ввод был каким-то образом разделен, например"меня зовут Фред" или "мое имя_ис_фред".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top