Bir dizenin ilk harfini büyük harfle yaz (maksimum performansla)


448

Bir var DetailsViewbir ile TextBox ve istediğim giriş veri edilmesi her zaman kaydedilir İLK MEKTUP SERMAYE ile.

Misal:

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

Bu maksimum performansa nasıl ulaşabilirim ?


NOT :
Cevaplara ve cevapların altındaki yorumlara dayanarak, birçok kişi bunun dizedeki tüm kelimeleri büyük harfle yazmayı istediğini düşünmektedir . Örneğin => Red House O değil, ama bu ne arıyorsun ise , cevapların that use biri için göz TextInfo'in ToTitleCaseyöntemi. (NOT: Bu yanıtlar, gerçekten sorulan soru için yanlıştır .) Uyarılar için TextInfo.ToTitleCase belgesine
bakın (tüm harflere sahip kelimelere dokunmazlar - kısaltma olarak kabul edilirler; "olmaması gereken" kelimelerin ortasındaki harfleri küçük harflerle yazabilirler indirgenmiş, örneğin "McDonald" => "Mcdonald"; büyük harf kullanım kurallarıyla ilgili tüm kültüre özgü incelikleri ele alacağı garanti edilmez.)


NOT :
sorudur belirsiz ilk sonra harfler gerekip gerekmediğini konusunda zorladı için harfe . Kabul edilen cevap sadece ilk harfin değiştirilmesi gerektiğini varsayar . Dizedeki ilk harflerin küçük harf olması için zorlamak istiyorsanız ToLower, ToTitleCase içeren ve içermeyen bir yanıt arayın .


7
@Bobby: Bu bir kopya değil: OP bir dizgenin ilk harfini büyük harfle yazmayı ister, bağlantıdaki soru her kelimenin ilk harfini büyük yapar.
GvS

1
@GvS: İlk cevap çok ayrıntılı ve ilk kod bloğu tam olarak aradığı şey. Ayrıca, her kelimeyi büyük harfle ilk kelimeye dönüştürmek arasında sadece bir döngü farkı vardır.
Bobby

Bunu başarıyla çözdünüz mü? Bununla ilgili hala yardıma mı ihtiyacınız var?
jcolebrand

1
Ama dediniz ki, "Her bir WORD büyük harfinin ilk harfini yap" diyorum. Bu nedenle, neden "kırmızı ev" -> "Kırmızı ev"? Neden "ev" in "h" harfi büyük değil?
Guillermo Gutiérrez

Başlangıçta bir boşluk varsa çoğu cevap başarısız olacağından bir yanıt eklendi. Bunu her cevaba göndermekten kaçınmak için buraya bir kez göndereceğim.
Noctis

Yanıtlar:


583

C # 8 olarak güncellendi

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);
        }
    }
}

Gerçekten eski cevaplar

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 : Bu sürüm daha kısadır. Daha hızlı bir çözüm için Equiso'nun cevabına bir göz atın

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

DÜZENLEME 2 : Muhtemelen en hızlı çözüm Darren'tır (Bir kıyaslama bile var), ancak string.IsNullOrEmpty(s)orijinal gereksinimin ilk harfin var olmasını beklediği için bir istisna atma doğrulamasını değiştireceğim . Bu kodun genel bir dize için çalıştığını ve özellikle Textbox.


2
Çünkü ilk parametresi, String.Joinikinci parametre ile verilen dizelerin birleştirileceği ayırıcıdır.
Dialecticus

27
Cevabınızı gerçekten seviyorum, ancak var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);daha az değişmez nesneler oluşturduğunuzdan (ve özellikle atladığınızdan String.Join) muhtemelen biraz hız kazanacaksınız . Bu elbette ipin uzunluğuna bağlıdır.
flindeberg

3
Harika - Linq kullanımı bu kodun ne yaptığını çok netleştirir.
Daniel James Bryars

7
Hmmm ... Teknik olarak, bu Büyük Harf Birinci Harf kuralına uymaya"Argh!" devam etmelidir . ;)
jp2code

2
@ jp2code Varolmayan bir ilk harfi boş veya boş bir dizgede büyük harflerle yazmak hamile bir yunusla tokatlanmak gibi, o zaman ALL CAPS ARGH! doğru yazımdır. urbandictionary.com/define.php?term=ARGH&defid=67839
Carlos Muñoz

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();
}

Eski cevap: Bu her ilk harfi büyük harfe çevirir

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

Ancak bu, bir sözcüğün her ilk harfini, yalnızca bir dizenin ilk karakterini değil, büyük harfe dönüştürür.
GvS

@GvS, soru sizden bunu yapmanızı istiyor.
thattolleyguy

17
"Kırmızı ev" => "Kırmızı ev" diye soruyor. ToTitleCase size "Red House" verecek.
GvS

1
bana yardımcı oldu. Harika
Ehsan Sajjad

1
Bundan emin değilim ama char + string bir boksa neden olur. Maksimum performansın gereklilik olması durumunda.
nawfal

164

Doğru yol Kültürü kullanmaktır:

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

Not: Bu, bir dizgideki her kelimeyi büyük harf olarak kullanır, örneğin "kırmızı ev" -> "Kırmızı Ev". Çözüm aynı zamanda kelimelerdeki büyük / küçük harfleri de azaltır, örneğin "eski McDonald" -> "Eski Mcdonald".


4
Bu, tekerleği yeniden icat etmek ve size kendi versiyonunu yazmaya çalışmak yerine bunu yapmanın en uygun yoludur.
Alexey Shevelyov

12
Bununla ilgili sorun, dize ortası olan potansiyel olarak geçerli büyük harfleri silmesidir. örneğin McNames
Jecoms

29
Bu, "kırmızı ev" in "Kırmızı Ev" haline gelmesinin yanlış bir cevabıdır ("H" ye dikkat edin)!
spaark

21
Soru sorulduktan altı yıl sonra, lütfen mevcut cevapları ve yorumlarını okumak için daha kapsamlı bir iş yapın . Daha iyi bir çözümünüz olduğuna ikna olduysanız , cevabınızın üstün olduğunu düşündüğünüz şekilde davrandığı durumları ve özellikle bunun mevcut cevaplardan nasıl farklı olduğunu gösterin . 1) Equiso, cevabının ikinci yarısında bu seçeneği zaten kapsadı. 2) Birçok durumda, ToLowerkelimenin tam anlamıyla büyük harf, örneğin "McDonalds" silmek gibi bir hatadır. 3) soru hakkındadır dize sadece ilk kelimesini değiştirerek , değil TitleCase hakkında.
ToolmakerSteve

10
Bu, girdiyi "Başlık Durumu" na dönüştürür - bu nedenle "kırmızı atı" "Kırmızı At" a çevirir - kişi bunu açıkça YAPMAMASI gerektiğini (ve "Kırmızı At" i döndürmesi gerektiğini) belirtir. Bu doğru yol değil.
Hekkaryk

68

En hızlı yöntemi http://www.dotnetperls.com/uppercase-first-letter adresinden aldım ve uzantı yöntemine dönüştürdüm:

    /// <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);
    }

Not: ToCharArraykullanım alternatifinden daha hızlı char.ToUpper(s[0]) + s.Substring(1), yalnızca bir dize tahsis edilirken, Substringyaklaşım alt dize için bir dize, sonra nihai sonucu oluşturmak için ikinci bir dize ayırır olmasıdır.


EDIT : İşte bu yaklaşım CarlosMuñoz kabul cevap ilk test ile birlikte nasıl görünüyor :

    /// <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);
    }

Vay, performans metriklerini bulduğunuz için teşekkürler, üstün performanslı bir çözüm gösterin!
ToolmakerSteve

@ToolmakerSteve, bu çözümü gerçekten diğerlerinden daha hızlı göründüğünden seviyorum, ancak bununla ilgili küçük bir sorun var. Null değerini iletirseniz çıktı olarak boş bir dize almamalısınız. Aslında, OP ilk harfi istediğinden boş bir dize geçirmenin bile bir istisna atması gerektiğini savunuyorum . Ayrıca, düzenlemeden önce başkalarının cevabı hakkında yorum yapabilirsiniz.
Carlos Muñoz

@ CarlosMuñoz - meta, diğer insanların cevaplarını "iyileştirmek" için tartışıldı. Fikir birliği "eğer bir cevabı geliştirebilirseniz, o zaman yapın - hiç kimse orijinal cevaba değil, cevaba" sahip değildir "- amaç mümkün olan en iyi cevaplara sahip olmaktır". Elbette düzenlemeyi düzenlemek veya geri almakta serbestsiniz. Bu durumda, ortak nezaket orijinal yazarın sürümünün nihai sonuç olmasına izin verirdi ve yorum yapmak için razı olurum. Genellikle yaptığım değişikliği de bir yorum yaptım; Yapmazsam özür dilerim.
ToolmakerSteve

@ CarlosMuñoz - özellikle, aktif olarak korunmayan SO'da çok, çok sayıda cevap var. Bir değişiklik bir cevabı iyileştirirse, neden bir yorumda gömülü kalsın? Yazar cevaplarını aktif olarak izliyorsa, uygun gördükleri değişiklikle ilgilenecektir. Eğer değillerse, cevap herkesin yararına geliştirildi. Bu ilke özellikle bu gibi eski Soru-Cevaplar için geçerlidir.
ToolmakerSteve

BTW, @ CarlosMuñoz ile yöntemin başlangıcındaki test hakkında hemfikirim - bu testin sürümü daha iyi programlama stili - return string.Emptyburada yönteme "kötü" bir çağrıyı gizleyecektim.
ToolmakerSteve

46

"ToTitleCase yöntemini" kullanabilirsiniz

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

bu genişletme yöntemi her titlecase problemini çözer.

kullanımı kolay

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

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

Genişletme yöntemi

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
    }
}

Sizin çözümünüzdeki sorun, "kırmızı ev" in "Kırmızı Ev" e dönüştürüleceği ve soruda "Kırmızı ev" e dönüştürülmeyeceğidir.
Vadim

3
@Tacttin Çalışacak ama aşağıdaki kodu okumak daha kolay ve daha iyi char.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ; Daha fazla bilgi @ vkreynin.wordpress.com/2013/10/09/…
Vadim

1
Bu çözümü sevmiyorum, çünkü iki farklı durumu tek bir uzun yöntemde birleştiriyor. Ben de kavramsal bir fayda görmüyorum. Ve sadece ilk harfi büyük harfle uygulamak gülünçtür. İlk harfi büyük yapmak istiyorsanız, açık uygulama sadece ilk harfi büyük harfle (ToUpper) kullanmaktır . Bunun yerine iki ayrı yöntemim olurdu. FirstLetterToUpperEquiso'nun cevabında (veya Guillernet'in yeni cevabında) ve ToTitleCaseburada, ancak ikinci parametre olmadan. O zaman gerek yok enum TitleCase.
ToolmakerSteve

31

İlk harf için hata denetimi ile:

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);
}

İşte kullanışlı bir uzantı ile aynı

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);
    }

Temiz yaklaşım. Teşekkür ederim!
Philippe

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

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

6

Performans / bellek kullanımı bir sorunsa, bu yalnızca Orijinal dize ile aynı boyutta bir (1) StringBuilder ve bir (1) yeni Dize oluşturur.

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
Bu char[], bir StringBuildersargının tüm altyapısına sahip olmak yerine basit bir yöntemle yapılabilir . Bunun yerine new StringBuilder(str), kullanın str.ToCharArray()ve yerine sb.ToString()kullanın new string(charArray). StringBuilderbir karakter dizisinin yerel olarak gösterdiği dizinleme türünü öykünür, böylece gerçek .ToUppersatır esasen aynı olabilir. :-)
Jonathan Gilbert

Darren (bir yıl sonra) ToCharArray@JonathanGilbert
ToolmakerSteve

6

En hızlı yöntem.

  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);
}

Testler sonraki sonuçları gösterir (giriş olarak 10000000 sembollü dize): Test sonuçları


1
sBoş veya boş olduğunda parametre döndürmenizi öneririm .
MatrixRonny

4

Bunu dene:

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

2
veya belki de başka bir karakter sınıfı (yani alfasayısal \ w), böylece işlev unicode farkında olur
Dmitry Ledentsov

@ DmitryLedentsov- C # string sınıfı UTF-16 karakterleri üzerine inşa edilmiştir. String Class "Metni UTF-16 kod birimlerinin dizisi olarak temsil eder."
ToolmakerSteve

4

Yalnızca ilk harfi büyük yazmayı önemsiyorsanız ve dizenin geri kalanı önemli değilse, sadece ilk karakteri seçebilir, büyük harf yapabilir ve orijinal ilk karakteri olmadan dizenin geri kalanıyla birleştirebilirsiniz.

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

İlk karakteri ToString () dönüştürmeliyiz çünkü bir Char dizisi olarak okuyoruz ve Char tipinde ToUpper () yöntemi yok.


3

İşte bunu bir uzantı yöntemi olarak yapmanın bir yolu:

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;
}

Daha sonra şöyle çağrılabilir:

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

Ve işte bunun için bazı birim testleri:

[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.Formataşırı dolu; basitçe yapın text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve

3

Bu konuda da çalıştığımdan ve herhangi bir fikir aradığından, bu geldiğim çözüm. LINQ kullanır ve ilk oluşum bir harf olmasa bile, bir dizenin ilk harfini büyük yazabilir. İşte yaptığım uzantı yöntemi.

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);
}

Eminim bunu biraz optimize etmenin veya temizlemenin bir yolu var.



3

Dizenin boş olup olmadığını kontrol edin, ardından ilk karakteri büyük harfe ve geri kalanını küçük harfe dönüştürün:

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

Sadece bir dize kelimesi için birkaç kod satırı yerine küçük çözüm için teşekkür ederiz!
Imran Faruqi

2

Bu, kelimenin başında olmayan hatalı başkentlerin olmadığından emin olmasına rağmen bunu yapacaktır.

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
sToTitleCase çağrısından önce boş bir kontrol gerekiyor.
Taras Alenin

@ CarlosMuñoz tlhIngan Hol'un senaryosunda harf kutusu yok. :-)
Jonathan Gilbert

2

İhtiyacınız olan tek şey burada çok fazla karmaşıklık var gibi görünüyor:

    /// <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);
    }

Dikkate değer noktalar:

  1. Bu bir uzatma yöntemidir.

  2. Giriş null, boş veya beyazsa giriş olduğu gibi döndürülür.

  3. String.IsNullOrWhiteSpace , .NET Framework 4 ile tanıtıldı. Bu, eski çerçevelerle çalışmaz.


1
Bunun, dört yıl önce kabul edilen orijinal cevapta nasıl bir gelişme olduğunu görmüyorum. Aslında, öyle tutarsız yeni kullanmanın tek faydası: (zararsız öyle, ama dört yıl geç, yeni bir cevap ekleyerek yararına yüksek standartlara sahip) IsNullOrWhiteSpaceyerine IsNullOrEmptysen yapacaksın olduğunu bulmak ve değiştirmek olmayan ilk boşluk . Ama sen yapmazsın - her zaman çalışırsın s[0]. Yani anlamsız [hem anlamsal hem de performans] kullanmak IsNullOrWhiteSpace.
ToolmakerSteve

... bu IsNullOrWhiteSpacebeni neden rahatsız ediyor, dikkatsiz bir okuyucunun "Beyaz boşluğu kontrol ettiğini, bu nedenle aşağıdaki kodun önünde beyaz boşluk olsa bile bir harf bulup değiştirdiğini" düşünebilmesidir. Kodunuz, önünde boşluk olan "ilk" harfi değiştiremeyeceğinden, kullanmak IsNullOrWhiteSpaceyalnızca bir okuyucuyu yanlış yönlendirebilir .
ToolmakerSteve

... Üzgünüz , kabul edilen cevabı değil, Equiso'nun aynı zaman dilimindeki cevabı kastediyorum .
ToolmakerSteve

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

Neden ToLower () kuyruğunda? Birinciden başka harflere gerek yoktur.
Carlos Muñoz

Stringherhangi bir şey olabilir Upperya da. yani Loweronun tüm dize için genel bir çözümdür.
Shailesh

Neden Joinyerine emp.First().ToString().ToUpper() + emp.Substring(1);? Muhtemelen çok daha savunmacı olması gerekir: output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Ayrıca, fwiw, @ CarlosMuñoz ile hemfikir - ToLower()OP sorusu için gerek yok .
Ağustos'ta

@ ruffin -> kullanarak Substring da iyi bir kod yazma tarzı, bir kod kırpmak için çözüm kabul ediyorum ama bu durumda bir yazma ToLower()iyi bir programlama uygulamasıdır. stringherhangi bir şey olabilir UpperDurum veya Lowerdurumda kullanıcı girdisine bağlıdır, ben genel bir çözüm vermek.
Shailesh

@Shailesh - Ancak, soru yoktu değil istemek sadece ilk harf sermaye olmak. İlk mektubun büyük harf olarak değiştirilmesini istedi. Yazardan daha fazla açıklama yapılmaksızın, en doğal varsayım, ipin geri kalanının değişmeden kalmasıdır. Üç yıl sonra yanıtladığınız düşünüldüğünde , lütfen kabul edilen cevabın askerin talep ettiği şeyi yaptığını varsayalım . Farklı bir cevap verebilmeniz için farklı bir teknik nedenin olması gerekir.
ToolmakerSteve

1

"MAKSİMUM PERFORMANS" cevabını vermek istedim. Zihnimde, bir "MAKSİMUM PERFORMANS" yanıtı tüm senaryoları yakalar ve bu senaryolar için soru muhasebesine cevap verir. İşte cevabım. Bu nedenlerle:

  1. IsNullOrWhiteSpace yalnızca boşluk veya boş / boş olan dizeleri açıklar.
  2. .Trim (), boşlukları dizenin önünden ve arkasından kaldırır.
  3. .First (), bir numaralandırılabilir (veya dize) ilk karakterini alır.
  4. Büyük harf olabilecek / olması gereken bir harf olup olmadığını kontrol etmeliyiz.
  5. Daha sonra dizenin geri kalanını ekleriz, ancak uzunluk yapmamız gerektiğini gösterirse.
  6. Net en iyi uygulama ile, System.Globalization.CultureInfo altında bir kültür sağlamalıyız.
  7. İsteğe bağlı parametreler olarak sağlanması, bu yöntemi seçilen kültürü her seferinde yazmak zorunda kalmadan tamamen yeniden kullanılabilir hale getirir.

    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
Bu çoğu durumu kapsıyor olsa da, her işlemde oluşturulan dizelerin sayısı göz önüne alındığında yavaş olmaz mı? Burada bir ton dize tahsisi var. Tercihen bir kez ve sadece bir kez tahsis edilir.
Douglas Gaskell

1

Son zamanlarda benzer bir gereksinim vardı ve LINQ işlevi Select () bir dizin sağlar hatırladı:

string input;
string output;

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

Çok sık ihtiyaç duyduğumdan dize türü için bir uzantı yöntemi yaptım:

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));
    }
}

Lütfen yalnızca ilk harfe büyük harfe dönüştürüldüğünü unutmayın; kalan tüm karakterlere dokunulmaz. Diğer karakterlerin küçük harf olması gerekiyorsa, dizin> 0 için Char.ToLower (currentChar) öğesini veya ilk sırada tüm dizede ToLower () öğesini de çağırabilirsiniz.

Performans açısından kodu Darren'ın çözümü ile karşılaştırdım. Makinemde Darren'ın kodu yaklaşık 2 kat daha hızlı, bu sadece bir char dizisindeki sadece ilk harfi düzenlediğinden sürpriz değil. Bu yüzden mevcut en hızlı çözüme ihtiyacınız varsa Darren kodunu almanızı öneririm. Diğer dize manipülasyonlarını da entegre etmek istiyorsanız, giriş dizesinin karakterlerine dokunan bir lambda işlevinin etkileyici gücüne sahip olmak uygun olabilir - bu işlevi kolayca genişletebilirsiniz - böylece bu çözümü burada bırakıyorum.


Bu sorunu nasıl çözeceğimi merak ettim, kendi çözümümü çözdüm, sonra sadece zaten sahip olduğum aynı çözümü bulduğunuzu bulmak için geri geldim. Sana +1!
BlueFuzzyThing

Çok teşekkür ederim.
Grimm

1

Aşağıdaki yöntemin en iyi çözüm olduğunu düşünüyorum

    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

ref


1

Bu soru performansı en üst düzeye çıkarmakla ilgili olarak Span, çöpü azaltan ve hızı yaklaşık% 10 artıran Darren'ın s sürümünü kullanmaya başladım .

        /// <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);
        }

Verim

|  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 |

Tam test kodu

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);
        }
    }

}

Düzenleme: s [0] yerine bir [0] yerine bir typeo vardı - bu, ayrılan Span a'ya cupying aynı, boş değerle sonuçlanır.


0

Bu, bu ilk harfi ve bir boşluktan sonraki her harfi büyük harflerle ve diğer harfleri küçük harflerle yazıyor.

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
Veya kod duvarlarını yazmak istemiyorsanız - CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); aynı şeyi yapar.
Chev

Evet ... Bunu bilmiyordum :) Ve büyük miktarda kodum yüzünden, hala yazarken herkesin cevapları ortaya çıktı.
thattolleyguy

ÖNEMLİ: 1) Bu cevap ve ToTitleCase arasındaki ufak bir fark, bu cevabın tümüyle büyük harf olan kelimeleri TitleCase olmaya zorlaması, ToTitleCase ise bu kelimeleri yalnız bırakmasıdır (kısaltma olabileceğini varsayar). İstenen bu olabilir veya olmayabilir. Bunun gibi bir kod örneğine sahip olmanın bir avantajı, istenildiği gibi değiştirilebilmesidir. 2) Bu, '' dışındaki beyaz boşlukları doğru şekilde işlemez. boşluk testini boşluk testi ile değiştirmelidir.
ToolmakerSteve

0

Aşağıdaki kodu kullanın:

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

Yıllar sonra eklenen bu cevabı düşürmek için benim temsilcimin bir anlamı bile yok, bu zaten mevcut cevaplara eşdeğer. Eğer bir soruya birçok cevap içeren yeni bir cevap ekleyecekseniz, lütfen cevabınızla ilgili neyin üstün olduğuna inandığınızı ya da hangi durumlarda cevabınızın diğer cevaplardan daha yararlı olacağını açıklayınız. Açık ol.
ToolmakerSteve

0

Burada verilen çözümlerin hiçbiri dizeden önce beyaz bir alanla uğraşmayacak gibi görünüyor.

Sadece bunu bir düşünce olarak eklemek:

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);
}   

Bu işlemesi gerektiğini this won't work on other answers(cümle başında bir boşluk olmadığını) ve kırpma boşluk gibi yapmazsanız sadece geçiş falseikinci parametre olarak (veya varsayılan değiştirmek falseve pas trueUzayda başa istiyorsanız)



0

Köknar mektubunu büyük harfle yazmanın en kolay yolu:

1- Sistem Kullanımı; Küreselleşme;

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

  myTI.ToTitleCase(textboxname.Text)

'


1
Bu cevap esasen yıllar önce verilen cevaplarla özdeştir . Tartışmaya hiçbir şey katmaz.
ToolmakerSteve

Aynı şey yanlıştır, tıpkı diğerinin yorumunda olduğu gibi, bu her ilk harfin tüm harflerinde yani Kızıl Ev yerine Kırmızı Ev değil, döner.
DeadlyChambers

0

aşağıdaki işlev tüm yollar için doğrudur:

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);
}

Onu burada buldum


Neden? Benzer görünen pek çok cevap varken neden başka bir cevap eklemeliyim ? Nesi var hepsi başka bir tane eklemek için istenmesine neden olan mevcut cevapları?
ToolmakerSteve

Çünkü bu yazılım her yönden doğrudur. Boşver.

Üzgünüm; Gereksiz yere sert davrandım. Gerçeklere sadık kalacağım: 1) Bu, yedi yıl önce thattolleyguy'un cevabı ile aynı . 2) Bu sorunun cevabı aynıdır: boş karakterden başka boşluk bırakmaz. 3) Bu OP'nin sorduğundan biraz farklı bir soruyu cevaplar. Tüm kelimelerin ilk harfinin büyük yazılmasını istiyorsanız, böyle bir cevap kullanın . 4) Genellikle bunu gerçekleştirmenin daha kolay yolu TitleInfo.ToTitleCase kullanmaktır. (Öte yandan, kod örneğinin bir avantajı istenildiği gibi özelleştirilebilir.)
ToolmakerSteve

Kendimi düzeltmek: Bu, tolleyguy'un yaklaşımından farklı: kelimenin ilk harfi olmayan dokunulmamış harfler bırakıyor. Bunun yerine, bir olan yinelenen bir zamoldar cevabı . Olumlu olarak, Darian'a kaynağa bağlantı verdiği için kudos - kredi vermeden zamoldar intihal gibi görünüyor. Bu kaynak bağlantıyı sağlayarak ve böylece tartışmayı geliştirdiğim için , eleştirmeme rağmen bu cevabı iptal ediyorum.
ToolmakerSteve

1
Darian yapılmış olabilir iki iyileştirmeler: 1) kullanmak char.IsWhiteSpace( array[ i -1 ] )yerine .. == ' 'tüm beyaz alanı işlemek için. 2) iki yeri kaldırın if (char.isLower(..))- hiçbir amaca hizmet etmezler . ToUpperbir karakter küçük harf değilse hiçbir şey yapmaz.
ToolmakerSteve

0

Yukarıdaki Carlos'un sorusunu genişleterek, birden fazla cümleyi büyük harfle yazmak istiyorsanız bu kodu kullanabilirsiniz:

    /// <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

Sorununuzu çözmek için olası çözüm.

   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();
   }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.