Crea la prima lettera di una stringa maiuscola (con le massime prestazioni)


448

Ho un DetailsViewcon un TextBox e voglio che i dati di input vengano salvati sempre con la PRIMA LETTERA IN CAPITALE.

Esempio:

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

Come posso ottenere questa prestazione massimizzante ?


NOTA : in
base alle risposte e ai commenti sotto le risposte, molte persone pensano che questo stia chiedendo di scrivere in maiuscolo tutte le parole nella stringa. Ad esempio => Red House , non lo è, ma se è quello che cerchi , cerca una delle risposte che utilizza TextInfoil ToTitleCasemetodo. (NOTA: quelle risposte non sono corrette per la domanda effettivamente posta).
Vedi il documento TextInfo.ToTitleCase per avvertimenti (non tocca le parole con tutti i caratteri maiuscoli - sono considerati acronimi; possono contenere lettere minuscole nel mezzo di parole che "non dovrebbero" essere abbassato, ad esempio "McDonald" => "Mcdonald"; non è garantito che gestisca tutte le sottigliezze specifiche della cultura in merito alle regole di capitalizzazione.)


NOTA :
la domanda è ambigua se le lettere dopo la prima debbano essere forzate in lettere minuscole . La risposta accettata presuppone che solo la prima lettera debba essere modificata . Se si desidera forzare tutte le lettere nella stringa tranne la prima in minuscolo, cercare una risposta contenente ToLowere non contenente ToTitleCase .


7
@Bobby: non è un duplicato: l'OP chiede di scrivere in maiuscolo la prima lettera di una stringa, la domanda nel collegamento mette in maiuscolo la prima lettera di ogni parola.
GvS,

1
@GvS: la prima risposta è molto dettagliata e il primo blocco di codice è esattamente quello che sta cercando. Inoltre, tra maiuscole e minuscole ogni parola è solo una differenza di ciclo.
Bobby,

Lo hai mai risolto con successo? Hai ancora bisogno di aiuto con questo?
jcolebrand,

1
Ma tu hai detto, e cito "Fai la prima lettera di OGNI PAROLA maiuscola". Pertanto, perché "casa rossa" -> "casa rossa"? Perché la "h" di "casa" non è una lettera maiuscola?
Guillermo Gutiérrez,

Aggiunta una risposta poiché la maggior parte delle risposte non riuscirà se si dispone di uno spazio bianco all'inizio. per evitare di pubblicarlo su ogni risposta, lo pubblicherò qui una volta.
Noctis,

Risposte:


583

Aggiornato a C # 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);
        }
    }
}

Risposte davvero vecchie

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 : questa versione è più breve. Per una soluzione più rapida dai un'occhiata alla risposta di 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 : Probabilmente la soluzione più veloce è quella di Darren (c'è persino un punto di riferimento) anche se cambierei la sua string.IsNullOrEmpty(s)convalida per generare un'eccezione poiché il requisito originale prevede che esista una prima lettera in modo che possa essere maiuscola. Si noti che questo codice funziona per una stringa generica e non in particolare su valori validi da Textbox.


2
Perché il primo parametro di String.Joinè un separatore con cui unire le stringhe fornite con il secondo parametro.
Dialecticus,

27
Mi piace molto la tua risposta, ma var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);probabilmente guadagnerei un po 'di velocità poiché stai creando oggetti meno immutabili (e soprattutto stai saltando String.Join). Questo ovviamente dipende dalla lunghezza della stringa.
flindeberg,

3
Fantastico - L'uso di Linq rende molto chiaro cosa fa questo codice.
Daniel James Bryars,

7
Hmmm ... Tecnicamente, questo dovrebbe tornare "Argh!"a rispettare la regola della prima lettera maiuscola. ;)
jp2code

2
@ jp2code Poiché scrivere in maiuscolo una prima lettera inesistente in una stringa nulla o vuota è come farsi schiaffeggiare da un delfino incinta, allora l'ARGH ALL CAPS! è l'ortografia corretta. 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();
}

Vecchia risposta: questo rende ogni prima lettera in maiuscolo

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

Ma questo converte ogni prima lettera di una parola in maiuscolo, non solo il primo carattere di una stringa.
GvS,

@GvS, ecco cosa ti chiede di fare.
thattolleyguy

17
Chiede "casa rossa" => "Casa rossa". ToTitleCase ti darà "Red House".
GvS,

1
utile per me. Grande
Ehsan Sajjad il

1
Non sono sicuro di ciò, ma char + string provoca un inscatolamento. Nel caso in cui sia richiesta la massima prestazione.
nawfal,

164

Il modo giusto è usare Cultura:

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

Nota: questo renderà maiuscole le parole all'interno di una stringa, ad es. "Casa rossa" -> "casa rossa". La soluzione prevede anche l'uso di lettere minuscole in lettere, ad esempio "vecchio McDonald" -> "Vecchio Mcdonald".


4
Questo è il modo più appropriato per farlo piuttosto che reinventare la ruota e provare a scrivere la tua versione di questo.
Alexey Shevelyov,

12
Il problema che ho con questo è che cancellerà le lettere maiuscole potenzialmente valide che sono a metà stringa. es. McNames
Jecoms

29
Questa è una risposta errata per il motivo che "casa rossa" diventa "Casa rossa" (notare la "H")!
spaark,

21
Sei anni dopo che è stata posta la domanda, ti preghiamo di fare un lavoro più approfondito nel leggere le risposte esistenti e i loro commenti . Se sei convinto di avere una soluzione migliore, mostra le situazioni in cui la tua risposta si comporta in un modo che ritieni sia superiore e in particolare in che modo differisce dalle risposte esistenti. 1) Equiso ha già trattato questa opzione, nella seconda metà della sua risposta. 2) Per molte situazioni, ToLowerè un errore, in quanto cancella le lettere maiuscole nel mezzo della parola, ad esempio "McDonalds". 3) La domanda è di cambiare solo la prima parola della stringa , non di TitleCase.
ToolmakerSteve

10
Questo trasforma l'input in "Caso del titolo" - quindi trasforma "cavallo rosso" in "Cavallo rosso" - mentre la persona che chiede esplicitamente ha dichiarato che NON dovrebbe farlo (e restituisce "Cavallo rosso"). Questo non è il modo giusto.
Hekkaryk,

69

Ho preso il metodo più veloce da http://www.dotnetperls.com/uppercase-first-letter e convertito in metodo di estensione:

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

NOTA: il motivo per cui ToCharArrayè più veloce dell'alternativa char.ToUpper(s[0]) + s.Substring(1)è che è allocata una sola stringa, mentre l' Substringapproccio alloca una stringa per la sottostringa, quindi una seconda stringa per comporre il risultato finale.


EDIT : Ecco come appare questo approccio, combinato con il test iniziale della risposta accettata da 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);
    }

Wow, grazie per aver trovato le metriche delle prestazioni, per mostrare una soluzione dalle prestazioni superiori!
ToolmakerSteve

@ToolmakerSteve, mi piace questa soluzione perché sembra davvero più veloce di altre, ma c'è un piccolo problema con questo. Se passi null, non dovresti ottenere una stringa vuota come output. In effetti, direi che anche il passaggio di una stringa vuota dovrebbe generare un'eccezione poiché l'OP chiede la prima lettera. Inoltre, puoi commentare la risposta di altre persone prima di modificarle.
Carlos Muñoz,

@ CarlosMuñoz - è stato discusso in meta, se "migliorare" le risposte degli altri. Il consenso era "se puoi migliorare una risposta, allora fallo - nessuno" possiede "una risposta, nemmeno l'autore originale - l'obiettivo è quello di avere le migliori risposte possibili". Naturalmente sei libero di modificare o ripristinare la modifica. In tal caso, la cortesia comune permetterebbe alla versione dell'autore originale di essere il risultato finale e mi accontenterei di commentare. Di solito inserisco anche in un commento la modifica che sto apportando; Mi scuso se non l'ho fatto.
ToolmakerSteve

@ CarlosMuñoz - in particolare, ci sono molte, molte risposte in SO, che non vengono mantenute attivamente. Se una modifica migliorasse una risposta, perché lasciarla sepolta in un commento? Se l'autore sta monitorando attivamente le loro risposte, farà il cambiamento nel modo che ritiene opportuno. In caso contrario, la risposta è stata migliorata, a beneficio di tutti. Questo principio è particolarmente vero, per le vecchie domande e risposte, come questo.
ToolmakerSteve l'

A proposito, sono d'accordo con @ CarlosMuñoz circa il test all'inizio del metodo - la sua versione di quel test è un migliore stile di programmazione - return string.Emptyqui nasconderebbe una "cattiva" chiamata al metodo.
ToolmakerSteve

46

Puoi usare "Metodo ToTitleCase"

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

questo metodo di estensione risolve ogni problema relativo al titolo.

facile da usare

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

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

il metodo di estensione

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

Il problema con la soluzione è che la "casa rossa" verrà convertita in "casa rossa" e non in "casa rossa" come è stato chiesto nella domanda.
Vadim,

3
@Tacttin Funzionerà ma il seguente codice è più facile da leggere ed esegue un carattere migliore.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ; Puoi leggere di più @ vkreynin.wordpress.com/2013/10/09/…
Vadim

1
Non mi piace questa soluzione, perché combina due situazioni abbastanza diverse in un unico metodo. Non vedo neanche un vantaggio concettuale. E l'implementazione di maiuscole solo nella prima lettera è ... ridicola. Se si desidera scrivere in maiuscolo la prima lettera, l'implementazione ovvia è solo capitalizzare (ToUpper) la prima lettera . Invece di questo, avrei due metodi separati. FirstLetterToUppernella risposta di Equiso (o nella risposta più recente di Guillernet) e ToTitleCasequi, ma senza il secondo parametro. Quindi non è necessario enum TitleCase.
ToolmakerSteve

31

Per la prima lettera, con controllo degli errori:

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

Ed ecco lo stesso di una pratica estensione

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

Approccio pulito. Grazie!
Philippe,

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

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

6

Se l'utilizzo delle prestazioni / memoria è un problema, questo crea solo un (1) StringBuilder e una (1) nuova stringa della stessa dimensione della stringa originale.

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
Questo potrebbe essere fatto con un semplice char[]anziché avere tutta l'infrastruttura di un StringBuilderavvolgimento. Invece di new StringBuilder(str), utilizzare str.ToCharArray()e invece di sb.ToString()utilizzare new string(charArray). StringBuilderemula il tipo di indicizzazione che una matrice di caratteri espone in modo nativo, quindi la .ToUpperriga effettiva può essere essenzialmente la stessa. :-)
Jonathan Gilbert,

Darren (un anno dopo) mostra come farlo usando ToCharArray, come suggerito da @JonathanGilbert
ToolmakerSteve

6

Metodo più veloce.

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

I test mostrano i risultati successivi (stringa con 10000000 simboli come input): risultati del test


1
Consiglio di restituire il sparametro quando è nullo o vuoto.
MatrixRonny,

4

Prova questo:

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

2
o forse qualche altra classe di caratteri (cioè alfanumerica \ w), in modo che la funzione sia a conoscenza
dell'unicode

@ DmitryLedentsov- La classe di stringhe C # è costruita su caratteri UTF-16. Classe stringa "Rappresenta il testo come una sequenza di unità di codice UTF-16."
ToolmakerSteve

4

Se ti interessa solo la prima lettera in maiuscolo e non importa il resto della stringa, puoi semplicemente selezionare il primo carattere, renderlo maiuscolo e concatenarlo con il resto della stringa senza il primo carattere originale.

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

Dobbiamo convertire il primo carattere ToString () perché lo stiamo leggendo come un array Char e il tipo Char non ha il metodo ToUpper ().


3

Ecco un modo per farlo come metodo di estensione:

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

Può quindi essere chiamato come:

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

Ed ecco alcuni test unitari per questo:

[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è eccessivo; semplicemente text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve

3

Da quando mi è capitato di lavorare anche su questo, e cercavo qualche idea, questa è la soluzione a cui sono arrivato. Utilizza LINQ e sarà in grado di scrivere in maiuscolo la prima lettera di una stringa, anche se la prima occorrenza non è una lettera. Ecco il metodo di estensione che ho finito per creare.

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

Sono sicuro che c'è un modo per ottimizzare o ripulire un po '.


3

Ho trovato qualcosa qui 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);
}

forse questo aiuta !!


In che modo questo è un miglioramento rispetto alla risposta di Equiso 4 anni prima?
ToolmakerSteve

3

Controlla se la stringa non è nulla quindi converti il ​​primo carattere in maiuscolo e il resto in minuscolo:

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

Grazie per la piccola soluzione anziché poche righe di codice solo per una parola stringa!
Imran Faruqi,

2

Questo lo farà anche se farà anche in modo che non ci siano capitali erranti che non sono all'inizio della parola.

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
È necessario un controllo null sprima della chiamata a ToTitleCase.
Taras Alenin,

@ CarlosMuñoz tlhIngan Hol non ha lettere nella sua sceneggiatura. :-)
Jonathan Gilbert,

2

Sembra esserci molta complessità qui quando tutto ciò che serve è:

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

Punti degni di nota:

  1. È un metodo di estensione.

  2. Se l'input è nullo, vuoto o vuoto, l'input viene restituito così com'è.

  3. String.IsNullOrWhiteSpace è stato introdotto con .NET Framework 4. Questo non funzionerà con i framework più vecchi.


1
Non vedo come questo sia un miglioramento rispetto alla risposta originale accettata di quattro anni fa. In realtà, è incoerente (innocuamente, ma con quattro anni di ritardo, ho standard elevati per una nuova risposta che aggiunge un vantaggio): l'unico vantaggio dell'uso del più recente IsNullOrWhiteSpaceinvece di IsNullOrEmpty, è se hai intenzione di trovare e cambiare il primo non- spazio bianco . Ma non lo fai - ci si opera sempre s[0]. Quindi è inutile [sia semanticamente che le prestazioni] da usare IsNullOrWhiteSpace.
ToolmakerSteve

... perché questo uso di IsNullOrWhiteSpaceme mi disturba, è che un lettore negligente potrebbe pensare "Ha controllato lo spazio bianco, quindi il seguente codice trova davvero e cambia una lettera, anche se è preceduto da uno spazio bianco". Poiché il tuo codice non riuscirà a cambiare una "prima" lettera preceduta da uno spazio bianco, l'utilizzo IsNullOrWhiteSpacepuò solo fuorviare un lettore.
ToolmakerSteve

... oops, non intendo la risposta accettata, intendo la risposta di Equiso dello stesso periodo di tempo.
ToolmakerSteve

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

Perché ToLower () alla coda ?. Non sono richieste altre lettere tranne la prima.
Carlos Muñoz,

Stringis può essere qualunque cosa sia Uppero Lower.so è una soluzione generica per tutte le stringhe.
Shailesh,

Perché Joininvece di emp.First().ToString().ToUpper() + emp.Substring(1);? Probabilmente bisogno di essere troppo più difensivo: output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Inoltre, concorda con @ CarlosMuñoz: non è necessario ToLower()per la domanda del PO.
ruffin,

@ ruffin -> usare Substring è anche un buon stile di scrittura del codice, concordo sulla tua soluzione per tagliare un codice ma in questo caso scrivere una ToLower()buona pratica di programmazione. stringpuò essere qualsiasi cosa Nel Uppercaso o nel Lowercaso dipenda dall'input dell'utente, fornisco una soluzione generica.
Shailesh,

@Shailesh - Tuttavia, la domanda non ha richiesto che solo la prima lettera fosse maiuscola. Ha chiesto che la prima lettera fosse cambiata in capitale. Senza ulteriori chiarimenti da parte dell'autore, il presupposto più naturale è che il resto della stringa rimanga invariato. Dato che stai rispondendo tre anni dopo , ti preghiamo di supporre che la risposta accettata faccia quello che il richiedente ha richiesto. Dare una risposta diversa solo se esiste qualche motivo tecnico per farlo diversamente.
ToolmakerSteve

1

Volevo fornire una risposta "MASSIMA PRESTAZIONE". Nella mia mente, una risposta "MASSIMA PRESTAZIONE" cattura tutti gli scenari e fornisce la risposta alla domanda tenendo conto di quegli scenari. Quindi, ecco la mia risposta. Con questi motivi:

  1. IsNullOrWhiteSpace tiene conto delle stringhe che sono solo spazi o null / vuote.
  2. .Trim () rimuove gli spazi bianchi dalla parte anteriore e posteriore della stringa.
  3. .First () accetta il primo carattere di un ienumerable (o stringa).
  4. Dovremmo verificare se è una lettera che può / dovrebbe essere maiuscola.
  5. Aggiungiamo quindi il resto della stringa, solo se la lunghezza indica che dovremmo.
  6. Secondo le migliori pratiche .Net, dovremmo fornire una cultura in System.Globalization.CultureInfo.
  7. Fornendoli come parametri opzionali, questo metodo è totalmente riutilizzabile, senza dover digitare ogni volta la cultura scelta.

    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
Sebbene ciò riguardi la maggior parte dei casi, non sarebbe piuttosto lento considerando il numero di stringhe create con ciascuna operazione? C'è un sacco di allocazione di stringhe in corso qui. Preferibilmente sarebbe assegnato una volta e una sola volta.
Douglas Gaskell,

1

Recentemente ho avuto un requisito simile e ho ricordato che la funzione LINQ Select () fornisce un indice:

string input;
string output;

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

Dato che mi serve molto spesso ho creato un metodo di estensione per il tipo di stringa:

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

Nota che solo la prima lettera viene convertita in maiuscolo, tutti i caratteri rimanenti non vengono toccati. Se hai bisogno che gli altri caratteri siano in minuscolo, puoi anche chiamare Char.ToLower (currentChar) per indice> 0 o chiamare ToLower () sull'intera stringa in primo luogo.

Per quanto riguarda le prestazioni, ho confrontato il codice con la soluzione di Darren. Sulla mia macchina il codice di Darren è circa 2 volte più veloce, il che non sorprende poiché sta modificando direttamente solo la prima lettera all'interno di un array di caratteri. Quindi ti suggerisco di prendere il codice di Darren se hai bisogno della soluzione più veloce disponibile. Se vuoi integrare anche altre manipolazioni di stringhe, può essere conveniente avere il potere espressivo di una funzione lambda che tocca i caratteri della stringa di input - puoi facilmente estendere questa funzione - quindi lascio questa soluzione qui.


Mi chiedevo come avrei risolto questo problema, elaborato la mia soluzione, poi sono tornato a pubblicarlo solo per scoprire che avevi trovato la stessa identica soluzione che avevo già. +1 a te!
BlueFuzzyThing

Grazie mille.
Grimm,

1

Penso che il metodo seguente sia la soluzione migliore

    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

arbitro


1

Poiché questa domanda riguarda l' ottimizzazione delle prestazioni, ho adottato la versione di Darren per utilizzare Spans, che riduce i rifiuti e migliora la velocità di circa il 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);
        }

Prestazione

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

Codice di prova completo

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

}

Modifica: c'era un errore di battitura, invece di s [0], era un [0] - questo risulta con lo stesso valore vuoto e vuoto allo Span allocato a.


0

Questo mette in maiuscolo questa prima lettera e ogni lettera che segue uno spazio e minuscole qualsiasi altra lettera.

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
O se non vuoi scrivere muri di codice - CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); fa la stessa cosa.
Chev,

Sì ... non lo sapevo :) E a causa della mia enorme quantità di codice, le risposte di tutti gli altri sono apparse mentre stavo ancora scrivendo.
thattolleyguy

AGGIORNATO: 1) Una leggera differenza tra questa risposta e ToTitleCase, è che questa risposta forza le parole che sono tutte maiuscole a diventare TitleCase, mentre ToTitleCase lascia tali parole da sole (presuppone che potrebbero essere acronimi). Questo potrebbe o non potrebbe essere ciò che si desidera. Un vantaggio di avere un esempio di codice come questo è che può essere modificato come desiderato. 2) questo non gestirà correttamente lo spazio bianco diverso da "". dovrebbe sostituire il test vuoto con il test dello spazio bianco.
ToolmakerSteve

0

Usa il seguente codice:

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

Non vale nemmeno la pena di sottovalutare il mio rappresentante per votare questa risposta aggiunta anni dopo, che è ovviamente equivalente a risposte già esistenti. Se hai intenzione di aggiungere una nuova risposta a una domanda con molte risposte, ti preghiamo di spiegare ciò che ritieni sia superiore alla tua risposta o in quali circostanze la tua risposta sarebbe più utile di altre risposte. Sii specifico.
ToolmakerSteve

0

Sembra che nessuna delle soluzioni fornite qui gestirà uno spazio bianco prima della stringa.

Basta aggiungere questo come pensiero:

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

Dovrebbe gestire this won't work on other answers(quella frase ha uno spazio all'inizio), e se non ti piace il taglio dello spazio, passa un falsesecondo parametro (o modifica il valore predefinito falsee passa truese vuoi occuparti dello spazio)



0

Il modo più semplice per capitalizzare la prima lettera è:

1- Utilizzo di Sytem.Globalization;

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

  myTI.ToTitleCase(textboxname.Text)

`


1
Questa risposta è essenzialmente identica alle risposte fornite anni prima. Non aggiunge nulla alla discussione.
ToolmakerSteve

È anche sbagliato, proprio come il commento nell'altra, questo trasforma ogni prima lettera in tutte le parole maiuscole, non Casa Rossa invece di Casa Rossa.
DeadlyChambers,

0

la seguente funzione è corretta per tutti i modi:

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

L'ho trovato qui


Perché? Perché aggiungere ancora un'altra risposta quando ci sono già così tante risposte che sembrano simili? Cosa c'è che non va in tutte le risposte esistenti che ti hanno spinto ad aggiungerne un'altra?
ToolmakerSteve

Perché questo Answare è corretto per tutti i modi. Calmati.

Mi dispiace; Ero inutilmente duro. Mi atterrò ai fatti: 1) Questo è essenzialmente lo stesso della risposta di quel carrello sette anni prima. 2) Questo ha lo stesso difetto di quella risposta: non gestisce spazi bianchi diversi dal carattere vuoto. 3) Questo risponde a una domanda leggermente diversa da quella che OP stava ponendo. Usa una risposta come questa se vuoi che tutte le parole abbiano la prima lettera maiuscola. 4) Di solito, il modo più semplice per farlo è usare TitleInfo.ToTitleCase. (D'altra parte, un vantaggio dell'esempio di codice è la possibilità di personalizzare come desiderato.)
ToolmakerSteve

Correggendo me stesso: questo è diverso dall'approccio di quel carrello: lascia lettere intatte che non sono la prima lettera della parola. Invece, è un duplicato della risposta di Zamoldar . Complimenti, complimenti a Darian per aver dato il collegamento alla fonte - sembra zamoldar plagiato senza dare credito. A causa di fornire quel link alla fonte, e quindi migliorare la discussione , sto votando questa risposta, nonostante le mie critiche.
ToolmakerSteve

1
Darian, due miglioramenti che potrebbero essere fatti: 1) usare char.IsWhiteSpace( array[ i -1 ] )invece di .. == ' ', per gestire tutto lo spazio bianco. 2) rimuovere i due punti che lo fanno if (char.isLower(..))- non servono a nulla. ToUppersemplicemente non fa nulla se un personaggio non è in minuscolo.
ToolmakerSteve

0

Espandendo la domanda di Carlos sopra, se vuoi capitalizzare più frasi puoi usare questo codice:

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

Possibile soluzione per risolvere il tuo problema.

   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();
   }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.