Як заголовити на C # перший символ кожного слова або перший символ цілого рядка?


82

Я міг би написати свій власний алгоритм для цього, але я відчуваю, що це має бути еквівалент гуманізації рубіну в C #.

Я погуглив, але знайшов лише способи гуманізувати дати.

Приклади:

  • Спосіб перетворити "Lorem Lipsum Et" на "Lorem lipum et"
  • Спосіб перетворити "Lorem lipum et" на "Lorem lipps et"

1
Мені подобається говорити Lorem Lipsum з якихось причин ^^
marcgg

3
Завжди є регулярні вирази! рядок strToCap = strSource.ToLower (); Regex rCapitalize = новий регулярний вираз ("(? <= [! \.?] \ S +) [A-Za-z]"); strToCap = rCapitalize.Replace (strToCap, m => {return m.Value.ToUpper ();}); ... але тоді у вас виникнуть ДВА проблеми. :)
rijipooh

3
Оскільки прийнята відповідь посилається на код, який робить протилежне тому, що просив вихідний запит, я відредагував запитання, щоб задати обидва напрямки, в надії, що це питання не буде абсолютно заплутаним для майбутніх користувачів, які натрапляють на нього .
Даніель Ервікер

Хоча, можливо, не виховується рядком прикладу OP, багато людей втрачають різницю між регістром заголовка та великими літерами. Заголовок не пише великими літерами загальні слова, тому, хоча він працює вище, це неправильне рішення. Собака швидка проти Собака швидка. Останнє - це використання великих літер.
demongolem

Відповіді:


138

Як обговорювалось у коментарях до відповіді @ miguel , ви можете використовувати те, TextInfo.ToTitleCaseщо було доступне з .NET 1.1. Ось код, що відповідає вашому прикладу:

string lipsum1 = "Lorem lipsum et";

// Creates a TextInfo based on the "en-US" culture.
TextInfo textInfo = new CultureInfo("en-US",false).TextInfo;

// Changes a string to titlecase.
Console.WriteLine("\"{0}\" to titlecase: {1}", 
                  lipsum1, 
                  textInfo.ToTitleCase( lipsum1 )); 

// Will output: "Lorem lipsum et" to titlecase: Lorem Lipsum Et

Він ігноруватиме тематичні коди, такі як "LOREM LIPSUM ET", оскільки він піклується про випадки, якщо скорочення є в тексті (щоб " NAMBLA " не перетворилося на "nambla" або "Nambla").

Однак, якщо ви хочете лише прописати великі літери першим символом, ви можете виконати рішення, яке закінчилося тут ... або ви можете просто розділити рядок і заголовити перший у списку:

string lipsum2 = "Lorem Lipsum Et";

string lipsum2lower = textInfo.ToLower(lipsum2);

string[] lipsum2split = lipsum2lower.Split(' ');

bool first = true;

foreach (string s in lipsum2split)
{
    if (first)
    {
        Console.Write("{0} ", textInfo.ToTitleCase(s));
        first = false;
    }
    else
    {
        Console.Write("{0} ", s);
    }
}

// Will output: Lorem lipsum et 

як більше людей не знають про це. Це чудовий вбудований метод, дякую
Купс

6
Ха-ха, 3 роки потому, і NAMBLA все ще змушує мене сміятися, о, і +1 для ToTitleCase ()
Джейсон Кулатунга

2
Знайдена проблема з ToTitleCase 1st стане 1St.
Йогурт Мудрий

1
Знайдено друге видання з ToTitleCase - & nbsp; стане & Nbsp;
Brain2000

2
@ Brain2000 Якщо ви знаєте, що в рядку є сутності HTML, вам слід дозволити коду обробляти це перед використанням ToTitleCase.
Spoike

33

Використовуйте регулярні вирази, щоб це виглядало набагато чистіше:

string s = "the quick brown fox jumps over the lazy dog";
s = Regex.Replace(s, @"(^\w)|(\s\w)", m => m.Value.ToUpper());

1
Розгортання відповіді: рядок s = "Швидке скачування лісових перемичок над ЛІНИМИ ДОГ"; s = Regex.Replace (s.ToLower (), @ "(^ \ w) | (\ s \ w)", m => m.Value.ToUpper ());
mcandal

8
Цей невлаштований вкладиш також працює: s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase (value.ToLower ());
Роберто

2
@Roberto - "hEm" -> регулярний вираз = "HEm"; "hEm" -> TitleCase = "Hem"
zzxyz

Я думаю, що це простішеRegex.Replace(s, @"\b([a-z])", m => m.Value.ToUpper())
Джон Хенкель,

29

Є ще одне елегантне рішення:

Визначте функцію ToTitleCaseв статичному класі вашого проекту

using System.Globalization;

public static string ToTitleCase(this string title)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(title.ToLower()); 
}

А потім використовуйте його як розширення рядка в будь-якому місці вашого проекту:

"have a good day !".ToTitleCase() // "Have A Good Day !"

2
Ви також повинні використовувати title.ToLower()перед переходом до ToTitleCase. В іншому випадку великі літери не заміняться.
РА.

2

Якщо ви просто хочете зробити великі літери першим символом, просто вставте це у свій власний метод:

return string.IsNullOrEmpty(str) 
    ? str
    : str[0].ToUpperInvariant() + str.Substring(1).ToLowerInvariant();

Існує також бібліотечний метод для написання першого символу кожного слова:

http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase.aspx


Це просто дасть вам регістр заголовка: "Lorem Ipsum Et", а не регістр речення: "Lorem ipsum et", так?
вінні

Я думаю, що це робить навпаки.
Чагдаш Текін

Я думав про це, але ToTitleCase - це протилежність того, що хоче OP.
Pat Hermens,

мій поганий, я думав, що це спрацює, але це не так. Здається, титульна книжка робить фокус
marcgg

Е-е-е ... Що таке титульна книжка? Ви маєте на увазі ToTitleCase? Це робить протилежне тому, що ви спочатку просили. Крім того, це найперше, що я опублікував у своїй оригінальній відповіді. Я здаюся.
Деніел Ервікер

1

Техніка CSS нормальна, але лише змінює подання рядка в браузері. Кращий метод - це зробити сам текст великими літерами перед надсиланням у браузер.

Більшість з наведених вище влучень є нормальними, але жодне з них не вирішує питання того, що відбувається, якщо у вас є змішані регістри, які потрібно зберегти, або якщо ви хочете використовувати справжній регістр заголовка, наприклад:

"Де вивчати курси PHd в США"

або

"Форма IRS UB40a"

Також за допомогою CultureInfo.CurrentCulture.TextInfo.ToTitleCase (рядок) зберігаються великі регістри, як у "sport and MLB baseball", який стає "Sports And MLB Baseball", але якщо вся рядок поставлена ​​у верхньому регістрі, це спричиняє проблему.

Отже, я зібрав просту функцію, яка дозволяє зберігати великі та мішані регістри та робити маленькі слова малими (якщо їх немає на початку та в кінці фрази), включаючи їх до масивів рядків specialCases і lowerCases:

public static string TitleCase(string value) {
        string titleString = ""; // destination string, this will be returned by function
        if (!String.IsNullOrEmpty(value)) {
            string[] lowerCases = new string[12] { "of", "the", "in", "a", "an", "to", "and", "at", "from", "by", "on", "or"}; // list of lower case words that should only be capitalised at start and end of title
            string[] specialCases = new string[7] { "UK", "USA", "IRS", "UCLA", "PHd", "UB40a", "MSc" }; // list of words that need capitalisation preserved at any point in title
            string[] words = value.ToLower().Split(' ');
            bool wordAdded = false; // flag to confirm whether this word appears in special case list
            int counter = 1;
            foreach (string s in words) {

                // check if word appears in lower case list
                foreach (string lcWord in lowerCases) {
                    if (s.ToLower() == lcWord) {
                        // if lower case word is the first or last word of the title then it still needs capital so skip this bit.
                        if (counter == 0 || counter == words.Length) { break; };
                        titleString += lcWord;
                        wordAdded = true;
                        break;
                    }
                }

                // check if word appears in special case list
                foreach (string scWord in specialCases) {
                    if (s.ToUpper() == scWord.ToUpper()) {
                        titleString += scWord;
                        wordAdded = true;
                        break;
                    }
                }

                if (!wordAdded) { // word does not appear in special cases or lower cases, so capitalise first letter and add to destination string
                    titleString += char.ToUpper(s[0]) + s.Substring(1).ToLower();
                }
                wordAdded = false;

                if (counter < words.Length) {
                    titleString += " "; //dont forget to add spaces back in again!
                }
                counter++;
            }
        }
        return titleString;
    }

Це лише швидкий і простий метод - і, можливо, його можна трохи вдосконалити, якщо ви хочете витратити на це більше часу.

якщо ви хочете зберегти великі літери менших слів, таких як "a" та "of", просто видаліть їх із масиву рядків для особливих випадків. Різні організації мають різні правила щодо використання великих літер.

Ви можете побачити приклад цього коду в дії на цьому веб-сайті: Пожертвування яєць Лондон - цей сайт автоматично створює стежки в верхній частині сторінок, аналізуючи URL-адресу, наприклад "/ services / uk-egg-bank / Introduction" - потім кожен у назві папки у сліді дефіси замінено на пробіли, а назва папки пишеться з великої літери, тому uk-egg-bank стає UK Egg Bank. (зберігаючи верхній регістр "Великобританія")

Розширенням цього коду може бути наявність таблиці пошуку абревіатур та великих / малих слів у спільному текстовому файлі, таблиці бази даних або веб-службі, щоб список змішаних регістрів можна було вести з одного місця та застосовувати до багатьох різних програми, які покладаються на функцію.


1

На всіх прикладах, здається, спочатку опускаються інші персонажі, що не те, що мені потрібно.

customerName= CustomerName<- Що саме я хотів

this is an example = This Is An Example

public static string ToUpperEveryWord(this string s)
{
    // Check for empty string.  
    if (string.IsNullOrEmpty(s))
    {
        return string.Empty;
    }

    var words = s.Split(' ');

    var t = "";
    foreach (var word in words)
    {
        t += char.ToUpper(word[0]) + word.Substring(1) + ' ';
    }
    return t.Trim();
}

0

У .NET не існує попередньо розробленого рішення для належної мовної капіталізації. На яку капіталізацію ви йдете? Чи дотримуєтесь ви конвенцій Чиказького керівництва стилем? AMA чи MLA? Навіть великі англійські речення з великої літери мають 1000 особливих винятків для слів. Я не можу говорити про те, що робить гуманізація рубіну, але, я думаю, це, швидше за все, не відповідає лінгвістичним правилам написання великої літери, а натомість робить щось набагато простіше.

Внутрішньо ми зіткнулися з цією ж проблемою і нам довелося написати досить великий код, щоб просто обробити правильний (у нашому маленькому світі) регістр заголовків статей, навіть не враховуючи використання великих літер речень. І це справді стає "нечітким" :)

Це насправді залежить від того, що вам потрібно - чому ви намагаєтесь перетворити речення на правильні великі літери (і в якому контексті)?


0

Я досяг того самого, використовуючи власні методи розширення. Для підрядка First Letter of First використовуйте метод yourString.ToFirstLetterUpper(). Для першої літери кожного підрядка, за винятком статей та деяких пропозицій , використовуйте метод yourString.ToAllFirstLetterInUpper(). Нижче представлена ​​консольна програма:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("this is my string".ToAllFirstLetterInUpper());
            Console.WriteLine("uniVersity of lonDon".ToAllFirstLetterInUpper());
        }
    }

    public static class StringExtension
    {
        public static string ToAllFirstLetterInUpper(this string str)
        {
            var array = str.Split(" ");

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == "" || array[i] == " " || listOfArticles_Prepositions().Contains(array[i])) continue;
                array[i] = array[i].ToFirstLetterUpper();
            }
            return string.Join(" ", array);
        }

        private static string ToFirstLetterUpper(this string str)
        {
            return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
        }

        private static string[] listOfArticles_Prepositions()
        {
            return new[]
            {
                "in","on","to","of","and","or","for","a","an","is"
            };
        }
    }

ВИХІД

This is My String
University of London
Process finished with exit code 0.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.