Створіть першу букву верхнього регістру рядка (з максимальною продуктивністю)


448

У мене є DetailsViewз TextBox і я хочу, щоб вхідні дані будуть збережені завжди з першою літерою КАПІТАЛУ.

Приклад:

"red" --> "Red"
"red house" --> " Red house"

Як я можу досягти цієї максимальної продуктивності ?


ПРИМІТКА .
На підставі відповідей та коментарів під відповідями багато людей думають, що це запитує про використання великих літер у всіх рядках. Наприклад , => Red House це не так , але якщо це те , що ви шукаєте , подивіться на один з відповідей , які використовує TextInfo«и ToTitleCaseметод. (ПРИМІТКА. Ці відповіді є невірними для фактично заданого питання.)
Дивіться документ TextInfo.ToTitleCase для застережень (не торкається слів з великими буквами - вони вважаються абревіатурами; вони можуть мати малі літери посеред слів, які "не повинні" бути знижений, наприклад, "McDonald" => "Макдональд"; не гарантовано обробляти всі специфічні для культури тонкощі щодо капіталізації.)


ПРИМІТКА :
Питання в тому , неоднозначне , чи є листи після того , як перший повинні бути змушені до нижнього регістру . Прийнята відповідь передбачає, що лише перша літера повинна бути змінена . Якщо ви хочете змусити всі літери в рядку, окрім першого, малі, шукайте відповідь, що містить ToLowerі не містить ToTitleCase .


7
@Bobby: Це не дублікат: ОП просить прописати велику літеру першої літери рядка, питання у посиланні з великої літери пише першу букву кожного слова.
GvS

1
@GvS: Перша відповідь дуже детальна, і перший блок коду - саме те , що він шукає. Також між великими літерами кожного слова та лише першим словом є лише одна різниця циклу.
Боббі

Ви коли-небудь успішно вирішили це? Вам все-таки потрібна допомога в цьому?
jcolebrand

1
Але ви сказали, і я цитую: "Складіть першу букву ВСЕ СЛОВО верхнє регістр". Тому чому "червоний будинок" -> "Червоний будинок"? Чому "h" "будинку" - це не велика літера?
Гільєрмо Гутьеррес

Додано відповідь, оскільки більшість відповідей не вдасться, якщо у вас є пробіл на початку. Щоб уникнути публікації цього запиту на кожну відповідь, я опублікую його тут один раз.
Ноктис

Відповіді:


583

Оновлено до № 8

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
            _ => input.First().ToString().ToUpper() + input.Substring(1)
        };
}

C # 7

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input.First().ToString().ToUpper() + input.Substring(1);
        }
    }
}

Дійсно старі відповіді

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
}

EDIT : Ця версія коротша. Для швидшого вирішення погляньте на відповідь Equiso

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + input.Substring(1);
}

EDIT 2 : Напевно, найшвидше рішення - це Даррен (Є навіть орієнтир), хоча я міняв би свою string.IsNullOrEmpty(s)перевірку, щоб кинути виняток, оскільки початкова вимога очікує існування першого листа, щоб воно могло бути рейтинговим. Зауважте, що цей код працює для загального рядка, а не особливо для дійсних значень з Textbox.


2
Тому що перший параметр - String.Joinце роздільник, за допомогою якого слід з'єднати рядки, задані другим параметром.
Діалектик

27
Мені дуже подобається ваша відповідь, але var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);, напевно, ви отримаєте деяку швидкість, оскільки ви створюєте менш непорушні об'єкти (і особливо ви їх пропускаєте String.Join). Це, звичайно, залежить від довжини струни.
Фліндеберг

3
Awesome - Використання Linq дає зрозуміти, що робить цей код.
Даніель Джеймс Брайарс

7
Гммм ... Технічно це має повернутися, "Argh!"щоб дотримуватися правила верхнього регістру Першого листа . ;)
jp2code

2
@ jp2code Оскільки велика літера неіснуючої першої літери в нульовій чи порожній рядку - це як потрапляння в дію за допомогою вагітного дельфінгу, то ВСІ КАПИ ARGH! - правильне написання. urbandictionary.com/define.php?term=ARGH&defid=67839
Карлос Муньос

319
public string FirstLetterToUpper(string str)
{
    if (str == null)
        return null;

    if (str.Length > 1)
        return char.ToUpper(str[0]) + str.Substring(1);

    return str.ToUpper();
}

Стара відповідь: це робить кожне перше лист великим регістром

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}

Але це перетворює кожну першу букву слова в великі регістри, а не лише перший символ рядка.
GvS

@GvS, саме це і задає вам питання.
thattolleyguy

17
Він запитує "червоний будинок" => "Червоний будинок". ToTitleCase подарує вам "Червоний дім".
GvS

1
корисна мені. Великий
Ехсан Саджад

1
Не впевнений у цьому, але char + string викликає бокс. Про всяк випадок, якщо вимога є максимальною.
nawfal

164

Правильний спосіб - це використовувати культуру:

System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())

Примітка. Це використовує великі літери у кожному рядку, наприклад, "червоний будинок" -> "Червоний дім". Рішення також буде писати великі літери у словах, наприклад, "старий Макдональд" -> "Старий Макдональд".


4
Це найбільш правильний спосіб зробити це, а не винаходити колесо і спробувати написати власну версію цього.
Олексій Шевельов

12
Проблема у мене полягає в тому, що він видалить потенційно дійсні великі літери, що є середніми рядками. наприклад McNames
Jecoms

29
Це неправильна відповідь з тієї причини, що "червоний будинок" стає "Червоним будинком" (зауважте "Н")!
spaark

21
Через шість років після того, як було поставлено запитання, прошу детальніше прочитати наявні відповіді та їх коментарі . Якщо ви переконані, що маєте краще рішення, то покажіть ситуації, в яких ваша відповідь веде себе так, як ви вважаєте, що вища, і конкретно, чим це відрізняється від існуючих відповідей. 1) Екісо вже охопив цей варіант у другій половині своєї відповіді. 2) У багатьох ситуаціях ToLowerє помилкою, оскільки вона стирає великі літери в середині слова, наприклад, "Макдональдс". 3) Питання полягає у зміні лише першого слова рядка , а не про TitleCase.
ToolmakerSteve

10
Це перетворює вхід у "Титульний кейс" - так він перетворює "червоного коня" на "Червоного коня" - в той час як людина, яка запитує, прямо заявила, що НЕ БУДЕ робити цього (і повернути "Червоний кінь"). Це не правильний шлях.
Хекарик

68

Я взяв найшвидший метод від http://www.dotnetperls.com/uppercase-first-letter і перейшов на метод розширення:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
    /// </summary>
    public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return string.Empty;

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

ПРИМІТКА. Причина використання ToCharArrayшвидша, ніж альтернатива char.ToUpper(s[0]) + s.Substring(1), полягає в тому, що виділяється лише одна рядок, тоді як Substringпідхід виділяє рядок для підрядка, а потім другий рядок для складання кінцевого результату.


EDIT : Ось як виглядає такий підхід у поєднанні з початковим тестом, прийнятим CarlosMuñoz :

    /// <summary>
    /// Returns the input string with the first character converted to uppercase
    /// </summary>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrEmpty(s))
            throw new ArgumentException("There is no first letter");

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

Нічого, дякую, що знайшли показники ефективності, щоб показати рішення про найкращу ефективність!
ToolmakerSteve

@ToolmakerSteve, мені подобається це рішення, оскільки воно справді здається швидшим за інших, але в цьому є невелика проблема. Якщо ви пропустите null, ви не повинні отримати порожній рядок як вихід. Насправді я б заперечував, що навіть проходження порожньої рядка повинно бути винятком, оскільки ОП вимагає першої літери. Також ви можете прокоментувати відповідь інших людей, перш ніж редагувати їх.
Карлос Муньос

@ CarlosMuñoz - це обговорювалося в мета, чи "покращувати" відповіді інших людей. Консенсус був "якщо ви можете вдосконалити відповідь, тоді зробіть це - ніхто не має" відповіді, навіть оригінальний автор - мета - отримати найкращі можливі відповіді ". Ви, звичайно, можете безкоштовно редагувати або відкидати зміни. У такому випадку звичайна ввічливість дозволила б оригінальній авторській версії бути остаточним результатом, і я погодився б коментувати. Зазвичай я також коментую зміни, які я вношу; Прошу вибачення, якщо цього не зробив.
ToolmakerSteve

@ CarlosMuñoz - зокрема, існує багато-багато відповідей в ТА, які активно не підтримуються. Якщо зміна покращить відповідь, навіщо залишати її похованою у коментарі? Якщо автор активно стежить за їхніми відповідями, він зробить із зміною так, як вважає за потрібне. Якщо їх немає, то відповідь було покращено, на користь кожному. Цей принцип особливо актуальний для старих запитань, таких як цей.
ToolmakerSteve

До речі, я погоджуюся з @ CarlosMuñoz щодо тесту на початку методу - його версія цього тесту є кращим стилем програмування - return string.Emptyтут буде приховано "поганий" виклик методу.
ToolmakerSteve

46

Ви можете використовувати "метод ToTitleCase"

string s = new CultureInfo("en-US").TextInfo.ToTitleCase("red house");
//result : Red House

цей метод розширення вирішує кожну проблему з заголовком.

простий у користуванні

string str = "red house";
str.ToTitleCase();
//result : Red house

string str = "red house";
str.ToTitleCase(TitleCase.All);
//result : Red House

метод розширення

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Test
{
    public static class StringHelper
    {
        private static CultureInfo ci = new CultureInfo("en-US");
        //Convert all first latter
        public static string ToTitleCase(this string str)
        {
            str = str.ToLower();
            var strArray = str.Split(' ');
            if (strArray.Length > 1)
            {
                strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                return string.Join(" ", strArray);
            }
            return ci.TextInfo.ToTitleCase(str);
        }
        public static string ToTitleCase(this string str, TitleCase tcase)
        {
            str = str.ToLower();
            switch (tcase)
            {
                case TitleCase.First:
                    var strArray = str.Split(' ');
                    if (strArray.Length > 1)
                    {
                        strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                        return string.Join(" ", strArray);
                    }
                    break;
                case TitleCase.All:
                    return ci.TextInfo.ToTitleCase(str);
                default:
                    break;
            }
            return ci.TextInfo.ToTitleCase(str);
        }
    }

    public enum TitleCase
    {
        First,
        All
    }
}

Проблема з вирішенням вашої проблеми полягає в тому, що "червоний будинок" буде перетворений на "червоний будинок", а не на "червоний будинок", як це було задано в питанні.
Вадим

3
@Tacttin Він буде працювати, але наступний код легше читати і виконує кращі функції char.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ; Ви можете прочитати більше @ vkreynin.wordpress.com/2013/10/09/…
Вадим

1
Мені це рішення не подобається, оскільки воно поєднує дві досить різні ситуації в один тривалий метод. Я також не бачу концептуальної вигоди. А реалізація великих букв лише першого листа є .. смішною. Якщо ви хочете використовувати великі літери першої літери, очевидною реалізацією є просто написання великої літери (ToUpper) першої літери . Замість цього я мав би два окремих методи. FirstLetterToUpperу відповіді Екісо (або у новій відповіді Гільєрне) і ToTitleCaseтут, але без другого параметра. Тоді не потрібно enum TitleCase.
ToolmakerSteve

31

Перший лист із перевіркою помилок:

public string CapitalizeFirstLetter(string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}

І ось те саме, що зручне продовження

public static string CapitalizeFirstLetter(this string s)
    {
    if (String.IsNullOrEmpty(s)) return s;
    if (s.Length == 1) return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
    }

Чистий підхід. Дякую!
Філіп

11
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}

6

Якщо продуктивність / використання пам’яті є проблемою, ця створює лише один (1) StringBuilder і один (1) новий рядок того ж розміру, що і початковий рядок.

public static string ToUpperFirst(this string str) {
  if( !string.IsNullOrEmpty( str ) ) {
    StringBuilder sb = new StringBuilder(str);
    sb[0] = char.ToUpper(sb[0]);

    return sb.ToString();

  } else return str;
}

3
Це можна зробити за допомогою простого, char[]а не з усією інфраструктурою StringBuilderобгортки. Замість цього new StringBuilder(str)використовуйте str.ToCharArray()та замість цього sb.ToString()використовуйте new string(charArray). StringBuilderемулює тип індексації, який символьний масив виставляє споконвічно, тому фактична .ToUpperлінія може бути по суті однаковою. :-)
Джонатан Гілберт

Даррен (через рік) показує, як це зробити, використовуючи ToCharArray, як запропонував @JonathanGilbert
ToolmakerSteve

6

Найшвидший метод.

  private string Capitalize(string s){
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
}

Тести показують наступні результати (рядок із 10000000 символів як вхід): Результати тесту


1
Я рекомендую повернути sпараметр, коли нуль або порожній.
MatrixRonny

4

Спробуйте це:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}

2
чи, можливо, якийсь інший клас символів (тобто буквено-цифровий \ w), так що функція не знає
коду,

@ Дмитрий Леденцов- клас струн C # побудований на символах UTF-16. Клас рядків "Представляє текст як послідовність кодових одиниць UTF-16."
ToolmakerSteve

4

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

String word ="red house";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = "Red house"

Нам потрібно перетворити ToString () першого символу (), оскільки ми читаємо його як масив Char, а тип Char не має методу ToUpper ().


3

Ось спосіб зробити це як метод розширення:

static public string UpperCaseFirstCharacter(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        return string.Format(
            "{0}{1}",
            text.Substring(0, 1).ToUpper(),
            text.Substring(1));
    }

    return text;
}

Потім можна назвати так:

//yields "This is Brian's test.":
"this is Brian's test.".UpperCaseFirstCharacter(); 

Ось кілька одиничних тестів для цього:

[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
    string orig = "";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(orig, result);
}

[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
    string orig = "c";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("C", result);
}

[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
    string orig = "this is Brian's test.";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("This is Brian's test.", result);
}

1
string.Formatнадмірність; просто робити text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve

3

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

public static string CaptalizeFirstLetter(this string data)
{
    var chars = data.ToCharArray();

    // Find the Index of the first letter
    var charac = data.First(char.IsLetter);
    var i = data.IndexOf(charac);

    // capitalize that letter
    chars[i] = char.ToUpper(chars[i]);

    return new string(chars);
}

Я впевнений, що існує спосіб трохи оптимізувати чи очистити це.


3

Щось тут я знайшов http://www.dotnetperls.com/uppercase-first-letter :

static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
    return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}

можливо, це допомагає !!


Яким чином це покращення порівняно з відповіддю Екісо на 4 роки раніше?
ToolmakerSteve

3

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

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}

Дякую за невелике рішення замість кількох рядків коду лише за рядкове слово!
Імран Фарукі

2

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

public string(string s)
{
System.Globalization.CultureInfo c = new System.Globalization.CultureInfo("en-us", false)
System.Globalization.TextInfo t = c.TextInfo;

return t.ToTitleCase(s);
}

2
sПотрібна перевірка нуля перед викликом ToTitleCase.
Тарас Аленін

@ CarlosMuñoz tlhIngan Hol не має в своєму сценарії обкладинки листів. :-)
Джонатан Гілберт

2

Здається, тут є багато складних ситуацій, коли все, що вам потрібно, це:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase if a letter
    /// </summary>
    /// <remarks>Null input returns null</remarks>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrWhiteSpace(s))
            return s;

        return char.ToUpper(s[0]) + s.Substring(1);
    }

Заслуговують на увагу моменти:

  1. Метод його розширення.

  2. Якщо введення недійсне, порожнє або пробіл, введення повертається таким, як є.

  3. String.IsNullOrWhiteSpace був представлений з .NET Framework 4. Це не працюватиме зі старими рамками.


1
Я не бачу, як це є покращенням оригінальної прийнятої відповіді від чотирьох років тому. Насправді це непослідовно (це нешкідливо, але на чотири роки пізніше у мене є високі стандарти щодо нової відповіді, що додає перевагу): Єдина користь від використання новішого, IsNullOrWhiteSpaceа не IsNullOrEmpty, якщо ви збираєтесь знайти та змінити перший, пробіл . Але ви цього не робите - ви завжди працюєте s[0]. Тож безглуздо [як семантично, так і продуктивно] використовувати IsNullOrWhiteSpace.
ToolmakerSteve

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

... ой, я не маю на увазі прийняту відповідь, я маю на увазі відповідь Екісо з того ж періоду часу.
ToolmakerSteve

1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();

Чому ToLower () у хвіст ?. Для інших букв, крім першого, немає жодної вимоги.
Карлос Муньоз

Stringє може бути будь-що його Upperабо. так Lowerце загальне рішення для всіх рядків.
Шайлеш

Чому Joinзамість emp.First().ToString().ToUpper() + emp.Substring(1);? Можливо , потрібно бути більш оборонними теж: output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Крім того, fwiw, погоджуйтеся з @ CarlosMuñoz - ToLower()для запитання про ОП вам не потрібно .
ruffin

@ ruffin -> використання Substring також хорошого стилю написання коду, я погоджуюся з вашим рішенням обрізати код, але в цьому випадку написання а ToLower()є гарною практикою програмування. stringможе бути будь-що У Upperвипадку або Lowerвипадку залежить від введення користувача, я даю загальне рішення.
Шайлеш

@Shailesh - Тим НЕ менше, питання навіть НЕ просити , що тільки перша буква буде прописаний. Він попросив змінити перший лист, щоб він був великим. Без додаткових пояснень з боку автора, найбільш природним припущенням є те, що залишок рядка повинен бути незмінним. Зважаючи на те, що ви відповідаєте через три роки , припустіть, що прийнята відповідь робить те, що просив запитувач. Дайте іншу відповідь, лише якщо є якісь технічні причини зробити це інакше.
ToolmakerSteve

1

Я хотів надати відповідь "МАКСИМАЛЬНА РОБОТА". На мій погляд, відповідь "МАКСИМАЛЬНА ВИКОНАННЯ" охоплює всі сценарії та дає відповідь на питання обліку цих сценаріїв. Отже, ось моя відповідь. З цих причин:

  1. IsNullOrWhiteSpace облікових записів для рядків, які є просто пробілами або null / empty.
  2. .Trim () видаляє пробіли з передньої та задньої частини рядка.
  3. .Перший () приймає перший символ незліченного (або рядка).
  4. Ми повинні перевірити, чи є це літерою, яка може / має бути великою літерою.
  5. Потім додаємо решту рядка, лише якщо довжина вказує, що ми повинні.
  6. За найкращою практикою .Net, ми повинні забезпечити культуру в рамках System.Globalization.CultureInfo.
  7. Надання їх як необов'язкових параметрів робить цей метод повністю багаторазовим, без необхідності щоразу вводити обрану культуру.

    public static string capString(string instring, string culture = "en-US", bool useSystem = false)
    {
        string outstring;
        if (String.IsNullOrWhiteSpace(instring))
        {
            return "";
        }
        instring = instring.Trim();
        char thisletter = instring.First();
        if (!char.IsLetter(thisletter))
        {
            return instring;   
        }
        outstring = thisletter.ToString().ToUpper(new CultureInfo(culture, useSystem));
        if (instring.Length > 1)
        {
            outstring += instring.Substring(1);
        }
        return outstring;
    }

2
Хоча це стосується більшості випадків, чи не буде це досить повільно, враховуючи кількість рядків, що створюються з кожною операцією? Тут відбувається виділення струн струни. Переважно це було б виділено один раз, і лише один раз.
Дуглас Гаскелл

1

Нещодавно у мене виникла подібна вимога і згадав, що функція LINQ Select () забезпечує індекс:

string input;
string output;

input = "red house";
output = String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
//output = "Red house"

Оскільки мені це потрібно дуже часто, я робив метод розширення для типу рядка:

public static class StringExtensions
{
    public static string FirstLetterToUpper(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return string.Empty;
        return String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
    }
}

Зверніть увагу, що лише перша літера перетворена у верхню букву - усі інші символи не торкаються. Якщо вам потрібні інші символи з малої літери, ви також можете зателефонувати Char.ToLower (currentChar) за індексом> 0 або подзвонити ToLower () у всій рядку в першу чергу.

Щодо продуктивності, я порівняв код із рішенням від Даррена. На моїй машині код Даррена приблизно в 2 рази швидший, що не дивно, оскільки він безпосередньо редагує лише першу букву в масиві char. Тому я пропоную вам взяти код Даррена, якщо вам потрібно найшвидше доступне рішення. Якщо ви хочете також інтегрувати інші рядкові маніпуляції, може бути зручно мати виразну силу функції лямбда, що торкається символів вхідного рядка - ви можете легко розширити цю функцію - тому я залишаю це рішення тут.


Мені було цікаво, як я вирішу цю проблему, я розробив власне рішення, а потім повернувся до публікації, лише щоб виявити, що ви придумали таке саме рішення, яке я вже мав. +1 вам!
BlueFuzzyThing

Дуже дякую.
Грімм

1

Я думаю, що наведений нижче метод - найкраще рішення

    class Program
{
    static string UppercaseWords(string value)
    {
        char[] array = value.ToCharArray();
        // Handle the first letter in the string.
        if (array.Length >= 1)
        {
            if (char.IsLower(array[0]))
            {
                array[0] = char.ToUpper(array[0]);
            }
        }
        // Scan through the letters, checking for spaces.
        // ... Uppercase the lowercase letters following spaces.
        for (int i = 1; i < array.Length; i++)
        {
            if (array[i - 1] == ' ')
            {
                if (char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
        }
        return new string(array);
    }

    static void Main()
    {
        // Uppercase words in these strings.
        const string value1 = "something in the way";
        const string value2 = "dot net PERLS";
        const string value3 = "String_two;three";
        const string value4 = " sam";
        // ... Compute the uppercase strings.
        Console.WriteLine(UppercaseWords(value1));
        Console.WriteLine(UppercaseWords(value2));
        Console.WriteLine(UppercaseWords(value3));
        Console.WriteLine(UppercaseWords(value4));
    }
}

Output

Something In The Way
Dot Net PERLS
String_two;three
 Sam

реф


1

Оскільки це питання стосується досягнення максимальної продуктивності, я прийняв версію Даррена для використання Spans, яка зменшує сміття та покращує швидкість приблизно на 10%.

        /// <summary>
        /// Returns the input string with the first character converted to uppercase
        /// </summary>
        public static string ToUpperFirst(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }

Продуктивність

|  Method |      Data |      Mean |     Error |    StdDev |
|-------- |---------- |----------:|----------:|----------:|
|  Carlos |       red | 107.29 ns | 2.2401 ns | 3.9234 ns |
|  Darren |       red |  30.93 ns | 0.9228 ns | 0.8632 ns |
| Marcell |       red |  26.99 ns | 0.3902 ns | 0.3459 ns |
|  Carlos | red house | 106.78 ns | 1.9713 ns | 1.8439 ns |
|  Darren | red house |  32.49 ns | 0.4253 ns | 0.3978 ns |
| Marcell | red house |  27.37 ns | 0.3888 ns | 0.3637 ns |

Повний код тесту

using System;
using System.Linq;

using BenchmarkDotNet.Attributes;

namespace CorePerformanceTest
{
    public class StringUpperTest
    {
        [Params("red", "red house")]
        public string Data;

        [Benchmark]
        public string Carlos() => Data.Carlos();

        [Benchmark]
        public string Darren() => Data.Darren();

        [Benchmark]
        public string Marcell() => Data.Marcell();
    }

    internal static class StringExtensions
    {
        public static string Carlos(this string input) =>
            input switch
            {
                null => throw new ArgumentNullException(nameof(input)),
                "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
                _ => input.First().ToString().ToUpper() + input.Substring(1)
            };

        public static string Darren(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            char[] a = s.ToCharArray();
            a[0] = char.ToUpper(a[0]);
            return new string(a);
        }

        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }
    }

}

Редагувати: замість s [0] був тип, а [0] - це призводить до зміни того ж, порожнього значення для виділеного Span a.


0

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

public string CapitalizeFirstLetterAfterSpace(string input)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);
    bool capitalizeNextLetter = true;
    for(int pos = 0; pos < sb.Length; pos++)
    {
        if(capitalizeNextLetter)
        {
            sb[pos]=System.Char.ToUpper(sb[pos]);
            capitalizeNextLetter = false;
        }
        else
        {
            sb[pos]=System.Char.ToLower(sb[pos]);
        }

        if(sb[pos]=' ')
        {
            capitalizeNextLetter=true;
        }
    }
}

1
Або якщо ви не хочете писати стіни коду - CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); робить те саме.
Шев

Так ... Я не знав про це :) І завдяки моїй великій кількості коду відповіді всіх інших спливали, поки я ще писав.
thattolleyguy

ЗАПОВНЕНО: 1) Невелика різниця між цією відповіддю та ToTitleCase полягає в тому, що ця відповідь змушує слова, які є всіма великими літерами, стати TitleCase, тоді як ToTitleCase залишає такі слова в спокої (припускає, що вони можуть бути абревіатурами). Це може бути або не бути тим, що бажано. Перевагою такого прикладу коду є те, що він може бути змінений за бажанням. 2) це не буде обробляти білий простір, крім '' правильно. слід замінити порожній тест тестом на пробіл.
ToolmakerSteve

0

Використовуйте наступний код:

string  strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();

На мою репутацію навіть не варто звертати увагу на цю відповідь, додану роками пізніше, що, очевидно, еквівалентно вже існуючим відповідям. Якщо ви збираєтесь додати нову відповідь на запитання з багатьма відповідями, поясніть, що ви вважаєте, що найкраще щодо вашої відповіді, або за яких обставин ваша відповідь була б кориснішою, ніж інші відповіді. Бути специфічним.
ToolmakerSteve

0

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

Просто додавши це як думку:

public static string SetFirstCharUpper2(string aValue, bool aIgonreLeadingSpaces = true)
{
    if (string.IsNullOrWhiteSpace(aValue))
        return aValue;

    string trimmed = aIgonreLeadingSpaces 
           ? aValue.TrimStart() 
           : aValue;

    return char.ToUpper(trimmed[0]) + trimmed.Substring(1);
}   

Він повинен обробляти this won't work on other answers(це речення має пробіл на початку), і якщо вам не подобається обрізка простору, просто передайте falseяк другий параметр (або змініть типовий параметр falseі передайте, trueякщо ви хочете мати справу з простором)



0

Найпростіший спосіб написання великої літери:

1- Використання Sytem.Globalization;

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

  myTI.ToTitleCase(textboxname.Text)

`


1
Ця відповідь по суті ідентична відповідям, даним роками раніше. Це нічого не додає до дискусій.
ToolmakerSteve

Це також неправильно, як і коментар в іншому, це перетворює кожну першу букву в усіх словах з великої літери, тобто Червоний дім замість Червоного дому.
DeadlyChambers

0

наступна функція правильна для всіх способів:

static string UppercaseWords(string value)
{
    char[] array = value.ToCharArray();
    // Handle the first letter in the string.
    if (array.Length >= 1)
    {
        if (char.IsLower(array[0]))
        {
            array[0] = char.ToUpper(array[0]);
        }
    }
    // Scan through the letters, checking for spaces.
    // ... Uppercase the lowercase letters following spaces.
    for (int i = 1; i < array.Length; i++)
    {
        if (array[i - 1] == ' ')
        {
            if (char.IsLower(array[i]))
            {
                array[i] = char.ToUpper(array[i]);
            }
        }
    }
    return new string(array);
}

Я знайшов це тут


Чому? Навіщо додати ще одну відповідь, коли вже так багато відповідей, які здаються схожими? Що не так у всіх існуючих відповідях, що спонукало вас додати ще одну?
ToolmakerSteve

Тому що це програмне забезпечення правильне для всіх способів. Заспокойся.

Вибачте; Мені було надмірно суворо. Я буду дотримуватися фактів: 1) Це по суті те саме , що відповідь цьоготоллігуя на сім років раніше. 2) Це має той самий недолік, що і відповідь: не обробляє пробіл, окрім порожнього символу. 3) Це дає відповідь на дещо інше запитання, ніж задало ОП. Використовуйте подібну відповідь, якщо ви хочете, щоб усі слова мали великі літери. 4) Зазвичай найпростіший спосіб досягти цього - використовувати TitleInfo.ToTitleCase. (З іншого боку, перевагу зразка коду можна налаштувати за бажанням.)
ToolmakerSteve

Виправлення самого себе: Це відрізняється від підходу до того, що підводить до нього: він залишає недоторкані літери, які не є першою літерою слова. Натомість це дублікат відповіді замолдара . Вигідно, кудо Даріану за надання посилання на джерело - здається, замолдар плагіат без надання кредиту. Через те, що надаю посилання на джерело і тим самим покращую дискусію , я підтримую цю відповідь, незважаючи на критику до неї.
ToolmakerSteve

1
Darian, два вдосконалення, які можна зробити: 1) використовувати char.IsWhiteSpace( array[ i -1 ] )замість .. == ' ', щоб обробити весь простір. 2) видаліть два місця, які if (char.isLower(..))вони виконують - вони не служать ніякій меті. ToUpperпросто нічого не робить, якщо персонаж не малий.
ToolmakerSteve

0

Розширюючи питання Карлоса вище, якщо ви хочете використовувати великі літери з кількох речень, ви можете використовувати цей код:

    /// <summary>
    /// Capitalize first letter of every sentence. 
    /// </summary>
    /// <param name="inputSting"></param>
    /// <returns></returns>
    public string CapitalizeSentences (string inputSting)
    {
        string result = string.Empty;
        if (!string.IsNullOrEmpty(inputSting))
        {
            string[] sentences = inputSting.Split('.');

            foreach (string sentence in sentences)
            {
                result += string.Format ("{0}{1}.", sentence.First().ToString().ToUpper(), sentence.Substring(1)); 
            }
        }

        return result; 
    }

0

Можливе рішення для вирішення вашої проблеми.

   public static string FirstToUpper(this string lowerWord)
   {
       if (string.IsNullOrWhiteSpace(lowerWord) || string.IsNullOrEmpty(lowerWord))
            return lowerWord;
       return new StringBuilder(lowerWord.Substring(0, 1).ToUpper())
                 .Append(lowerWord.Substring(1))
                 .ToString();
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.