Faire la première lettre d'une chaîne en majuscules (avec des performances maximales)

447

J'ai un DetailsViewavec un TextBox et je veux que les données d'entrée soient toujours enregistrées avec la PREMIÈRE LETTRE EN MAJUSCULE.

Exemple:

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

Comment puis-je atteindre ces performances maximales ?


REMARQUE :
Sur la base des réponses et des commentaires sous les réponses, de nombreuses personnes pensent que cela demande de mettre en majuscule tous les mots de la chaîne. Par exemple, => Red House ce n'est pas le cas, mais si c'est ce que vous cherchez , recherchez l'une des réponses qui utilise TextInfola ToTitleCaseméthode de. (REMARQUE: ces réponses sont incorrectes pour la question réellement posée.)
Voir le document TextInfo.ToTitleCase pour les mises en garde (ne touche pas les mots en majuscules - ils sont considérés comme des acronymes; peut minuscules au milieu des mots qui "ne devraient pas" être abaissé, par exemple "McDonald" => "Mcdonald"; il n'est pas garanti de gérer toutes les subtilités propres à la culture concernant les règles de capitalisation.)


REMARQUE :
la question est ambiguë de savoir si les lettres après la première doivent être forcées en minuscules . La réponse acceptée suppose que seule la première lettre doit être modifiée . Si vous souhaitez forcer toutes les lettres de la chaîne, sauf la première à être en minuscules, recherchez une réponse contenant ToLoweret ne contenant pas ToTitleCase .

dylan-myers
la source
7
@Bobby: Ce n'est pas un doublon: l'OP demande de mettre en majuscule la première lettre d'une chaîne, la question dans le lien met en majuscule la première lettre de chaque mot.
GvS
1
@GvS: La première réponse est très détaillée et le premier bloc de code est exactement ce qu'il recherche. En outre, entre la mise en majuscule de chaque mot et uniquement le premier mot est une seule différence de boucle.
Bobby
Avez-vous déjà réussi à résoudre ce problème? Avez-vous encore besoin d'aide pour cela?
jcolebrand
1
Mais vous avez dit, et je cite: "Faites la première lettre de CHAQUE MOT en majuscules". Par conséquent, pourquoi "maison rouge" -> "Maison rouge"? Pourquoi le "h" de "maison" n'est pas une majuscule?
Guillermo Gutiérrez
Ajout d'une réponse car la plupart des réponses échoueront si vous avez un espace blanc au début. afin d'éviter de poster ceci sur chaque réponse, je le posterai ici une fois.
Noctis

Réponses:

583

Mis à jour en 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);
        }
    }
}

Vraiment vieilles réponses

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 : Cette version est plus courte. Pour une solution plus rapide, jetez un œil à la réponse d'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 : La solution la plus rapide est probablement celle de Darren (il y a même un point de référence) bien que je changerais sa string.IsNullOrEmpty(s)validation pour lever une exception puisque l'exigence d'origine s'attend à ce qu'une première lettre existe afin qu'elle puisse être mise en majuscule. Notez que ce code fonctionne pour une chaîne générique et pas particulièrement sur les valeurs valides du Textbox.

Carlos Muñoz
la source
2
Parce que le premier paramètre de String.Joinest le séparateur avec lequel joindre les chaînes données avec le deuxième paramètre.
Dialecticus
27
J'aime vraiment votre réponse, mais var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);gagnerait probablement un peu de vitesse puisque vous créez des objets moins immuables (et surtout vous sautez le String.Join). Cela dépend bien sûr de la longueur de la chaîne.
flindeberg
3
Génial - L'utilisation de Linq rend très clair ce que fait ce code.
Daniel James Bryars
7
Hmmm ... Techniquement, cela devrait revenir "Argh!"conformément à la règle de la première lettre majuscule. ;)
jp2code
2
@ jp2code Étant donné que la mise en majuscule d'une première lettre inexistante dans une chaîne nulle ou vide, c'est comme se faire gifler par un dauphing enceinte, alors l'ARGH ALL CAPS! est l'orthographe correcte. 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();
}

Ancienne réponse: chaque première lettre est en majuscule

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
Diego Torres
la source
Mais cela convertit chaque première lettre d'un mot en majuscules, pas seulement le premier caractère d'une chaîne.
GvS
@GvS, c'est ce que la question vous demande de faire.
thattolleyguy
17
Il demande "maison rouge" => "Maison rouge". ToTitleCase vous donnera "Red House".
GvS
1
utile pour moi. Génial
Ehsan Sajjad
1
Pas sûr à ce sujet, mais char + string provoque une boxe. Juste au cas où des performances maximales seraient requises.
nawfal
163

La bonne façon est d'utiliser Culture:

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

Remarque: Cela mettra en majuscule chaque mot dans une chaîne, par exemple "maison rouge" -> "maison rouge". La solution réduira également les majuscules en lettres minuscules, par exemple «vieux McDonald» -> «Old Mcdonald».

Pierre-Yves Guillemet
la source
4
C'est la façon la plus appropriée de le faire plutôt que de réinventer la roue et d'essayer d'écrire votre propre version de cela.
Alexey Shevelyov
12
Le problème que j'ai avec ceci est qu'il effacera les majuscules potentiellement valides qui sont à mi-chaîne. par exemple McNames
Jecoms
29
Ceci est une réponse incorrecte car la "maison rouge" devient "la maison rouge" (remarquez le "H")!
spaark
21
Six ans après que la question a été posée, veuillez lire plus attentivement les réponses existantes et leurs commentaires . Si vous êtes convaincu que vous avez une meilleure solution, montrez les situations dans lesquelles votre réponse se comporte d'une manière que vous jugez supérieure, et en particulier en quoi elle diffère des réponses existantes. 1) Equiso a déjà couvert cette option, dans la seconde moitié de sa réponse. 2) Dans de nombreuses situations, ToLowerc'est une erreur, car elle efface la capitalisation au milieu du mot, par exemple "McDonalds". 3) La question est de ne changer que le premier mot de la chaîne , pas de TitleCase.
ToolmakerSteve
10
Ceci transforme l'entrée en "Case Titre" - donc elle transforme "cheval rouge" en "Cheval rouge" - tandis que la personne demandant explicitement a déclaré qu'elle ne devrait PAS faire cela (et retourner "Cheval rouge"). Ce n'est pas la bonne façon.
Hekkaryk
68

J'ai pris la méthode la plus rapide de http://www.dotnetperls.com/uppercase-first-letter et converti en méthode d'extension:

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

REMARQUE: la raison pour laquelle l'utilisation ToCharArrayest plus rapide que l'alternative char.ToUpper(s[0]) + s.Substring(1)est qu'une seule chaîne est allouée, tandis que l' Substringapproche alloue une chaîne pour la sous-chaîne, puis une deuxième chaîne pour composer le résultat final.


EDIT : Voici à quoi ressemble cette approche, combinée avec le test initial de la réponse acceptée de 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);
    }
Darren
la source
Wow, merci d'avoir trouvé des mesures de performance, pour montrer une solution de performance supérieure!
ToolmakerSteve
@ToolmakerSteve, j'aime cette solution car elle semble en effet plus rapide que les autres mais il y a un petit problème avec ça. Si vous passez null, vous ne devriez pas obtenir une chaîne vide en sortie. En fait, je dirais que même le passage d'une chaîne vide devrait lever une exception puisque l'OP demande la première lettre. Vous pouvez également commenter la réponse des autres avant de les modifier.
Carlos Muñoz
@ CarlosMuñoz - il a été discuté dans la méta, si "améliorer" les réponses des autres. Le consensus était "si vous pouvez améliorer une réponse, alors faites-le - personne ne" possède "une réponse, pas même l'auteur original - le but est d'avoir les meilleures réponses possibles". Vous êtes bien sûr libre de modifier ou d'annuler la modification. Dans ce cas, la courtoisie générale laisserait la version originale de l'auteur être le résultat final, et je me contenterais de commenter. Habituellement, je mets également dans un commentaire le changement que j'apporte; Je m'excuse si je ne l'ai pas fait.
ToolmakerSteve
@ CarlosMuñoz - en particulier, il y a beaucoup, beaucoup de réponses dans SO, qui ne sont pas activement maintenues. Si un changement améliore une réponse, pourquoi le laisser enterré dans un commentaire? Si l'auteur surveille activement ses réponses, il fera le changement comme bon lui semble. S'ils ne le sont pas, la réponse a été améliorée, pour le bien de tous. Ce principe est particulièrement vrai pour les anciens Q&R, comme celui-ci.
ToolmakerSteve
BTW, je suis d'accord avec @ CarlosMuñoz sur le test au début de la méthode - sa version de ce test est un meilleur style de programmation - l' return string.Emptyici cacherait un "mauvais" appel à la méthode.
ToolmakerSteve
46

Vous pouvez utiliser la "méthode ToTitleCase"

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

cette méthode d'extension résout tous les problèmes de casse.

facile à utiliser

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

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

la méthode d'extension

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
    }
}
İbrahim Özbölük
la source
Le problème avec votre solution est que "maison rouge" sera convertie en "maison rouge" et non en "maison rouge" comme cela a été demandé dans la question.
Vadim
3
@Tacttin Cela fonctionnera mais le code suivant est plus facile à lire et exécute mieux char.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ; Vous pouvez lire plus @ vkreynin.wordpress.com/2013/10/09/…
Vadim
1
Je n'aime pas cette solution, car elle combine deux situations très différentes en une seule méthode longue. Je ne vois pas non plus d'avantage conceptuel. Et la mise en œuvre de la mise en majuscule de la première lettre seulement est… ridicule. Si vous souhaitez mettre en majuscule la première lettre, l'implémentation évidente consiste simplement à mettre en majuscule (ToUpper) la première lettre . Au lieu de cela, j'aurais deux méthodes distinctes. FirstLetterToUpperdans la réponse d'Equiso (ou dans la réponse plus récente de Guillernet), et ToTitleCaseici, mais sans le deuxième paramètre. Alors pas besoin enum TitleCase.
ToolmakerSteve
31

Pour la première lettre, avec vérification d'erreur:

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

Et voici la même chose qu'une extension pratique

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);
    }
Kobi
la source
Approche propre. Je vous remercie!
Philippe
11
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}
Big T
la source
6

Si les performances / l'utilisation de la mémoire sont un problème, celui-ci ne crée qu'un (1) StringBuilder et une (1) nouvelle chaîne de la même taille que la chaîne d'origine.

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;
}
Daniel Halan
la source
3
Cela pourrait être fait avec un simple char[]plutôt que d'avoir toute l'infrastructure d'un StringBuilderenveloppement. Au lieu de new StringBuilder(str), utilisez str.ToCharArray()et au lieu de sb.ToString(), utilisez new string(charArray). StringBuilderémule le type d'indexation qu'un tableau de caractères expose nativement, de sorte que la .ToUpperligne réelle peut être essentiellement la même. :-)
Jonathan Gilbert
Darren (un an plus tard) montre comment faire cela en utilisant ToCharArray, comme suggéré par @JonathanGilbert
ToolmakerSteve
6

Méthode la plus rapide.

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

Les tests montrent les résultats suivants (chaîne avec 10000000 symboles en entrée): Résultats des tests

Александр Иванов
la source
1
Je recommande de retourner le sparamètre lorsqu'il est nul ou vide.
MatrixRonny
4

Essaye ça:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}
JoelFan
la source
2
ou peut-être une autre classe de caractères (c'est-à-dire alphanumérique \ w), de sorte que la fonction soit sensible à l'unicode
Dmitry Ledentsov
@ DmitryLedentsov - La classe de chaînes C # est construite sur des caractères UTF-16. String Class "Représente le texte comme une séquence d'unités de code UTF-16."
ToolmakerSteve
4

Si vous ne vous souciez que de la première lettre en majuscule et que le reste de la chaîne importe peu, vous pouvez simplement sélectionner le premier caractère, le mettre en majuscule et le concaténer avec le reste de la chaîne sans le premier caractère d'origine.

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

Nous devons convertir le premier caractère ToString () car nous le lisons en tant que tableau Char, et le type Char n'a pas de méthode ToUpper ().

Víctor García
la source
3

Voici un moyen de le faire comme méthode d'extension:

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

Peut alors être appelé comme:

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

Et voici quelques tests unitaires pour cela:

[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);
}
bingles
la source
1
string.Formatest exagéré; faites simplement text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve
3

Comme il m'arrivait de travailler là-dessus également et que je cherchais des idées, c'est la solution à laquelle je suis parvenu. Il utilise LINQ et pourra mettre en majuscule la première lettre d'une chaîne, même si la première occurrence n'est pas une lettre. Voici la méthode d'extension que j'ai fini par faire.

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

Je suis sûr qu'il existe un moyen d'optimiser ou de nettoyer un peu cela.

CAOakley
la source
3

J'ai trouvé quelque chose ici 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);
}

peut-être que cela aide !!

Mohammed Zameer
la source
En quoi est-ce une amélioration par rapport à la réponse d'Equiso 4 ans plus tôt?
ToolmakerSteve
3

Vérifiez si la chaîne n'est pas nulle, puis convertissez le premier caractère en majuscules et le reste en minuscules:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}
mbadeveloper
la source
Merci pour la petite solution au lieu de quelques lignes de code juste pour un mot chaîne!
Imran Faruqi
2

Cela le fera bien qu'il s'assurera également qu'il n'y a pas de majuscules errantes qui ne sont pas au début du mot.

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);
}
Jeff Hornby
la source
2
Nécessite une vérification nulle savant l'appel à ToTitleCase.
Taras Alenin
@ CarlosMuñoz tlhIngan Hol n'a pas de casse de lettre dans son script. :-)
Jonathan Gilbert
2

Il semble y avoir beaucoup de complexité ici quand tout ce dont vous avez besoin est:

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

Points remarquables:

  1. C'est une méthode d'extension.

  2. Si l'entrée est nulle, vide ou en blanc, l'entrée est renvoyée telle quelle.

  3. String.IsNullOrWhiteSpace a été introduit avec .NET Framework 4. Cela ne fonctionnera pas avec les anciens frameworks.

Stephen Kennedy
la source
1
Je ne vois pas en quoi il s'agit d'une amélioration par rapport à la réponse initialement acceptée d'il y a quatre ans. En fait, il est incohérent (de manière inoffensive, mais avec quatre ans de retard, j'ai des normes élevées pour une nouvelle réponse ajoutant un avantage): le seul avantage d'utiliser le plus récent IsNullOrWhiteSpaceplutôt que IsNullOrEmpty, c'est si vous allez trouver et modifier le premier non espace blanc . Mais vous ne le faites pas - vous opérez toujours s[0]. Donc, c'est inutile [à la fois sémantiquement et performance] à utiliser IsNullOrWhiteSpace.
ToolmakerSteve
... pourquoi cette utilisation de IsNullOrWhiteSpaceme dérange, c'est qu'un lecteur imprudent pourrait penser "Il a vérifié les espaces blancs, donc le code suivant trouve et modifie vraiment une lettre, même si elle est précédée d'un espace blanc". Étant donné que votre code ne parviendra pas à modifier une "première" lettre précédée d'un espace blanc, l'utilisation IsNullOrWhiteSpacene peut qu'induire le lecteur en erreur .
ToolmakerSteve
... oups, je ne veux pas dire la réponse acceptée, je veux dire la réponse d' Equiso de la même période.
ToolmakerSteve
1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();
Shailesh
la source
Pourquoi ToLower () à la queue?. Il n'y a aucune exigence pour les autres lettres, mais la première.
Carlos Muñoz
Stringis peut être n'importe quoi son Upperou Lower.so c'est une solution générique pour toutes les chaînes.
Shailesh
Pourquoi Joinau lieu de emp.First().ToString().ToUpper() + emp.Substring(1);? Probablement besoin d'être plus défensive aussi: output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Aussi, fwiw, d'accord avec @ CarlosMuñoz - vous n'avez pas besoin du ToLower()pour la question du PO.
ruffin
@ ruffin -> l'utilisation Substring est également un bon style d'écriture de code, je suis d'accord avec votre solution pour couper un code, mais dans ce cas, écrire un ToLower()est une bonne pratique de programmation. stringpeut être n'importe quoi Dans le Uppercas ou le Lowercas dépend de l'entrée de l'utilisateur, je donne une solution générique.
Shailesh
@Shailesh - Cependant, la question ne demandait pas que seule la première lettre soit une majuscule. Il a demandé que la première lettre soit remplacée par une majuscule. Sans autre précision de l'auteur, l'hypothèse la plus naturelle est que le reste de la chaîne soit inchangé. Étant donné que vous répondez trois ans plus tard , veuillez supposer que la réponse acceptée fait ce que le demandeur a demandé. Donnez une réponse différente uniquement s'il existe une raison technique de procéder différemment.
ToolmakerSteve
1

Je voulais apporter une réponse "PERFORMANCE MAXIMALE". Dans mon esprit, une réponse "PERFORMANCE MAXIMALE" capture tous les scénarios et fournit la réponse à la question expliquant ces scénarios. Alors, voici ma réponse. Pour ces raisons:

  1. IsNullOrWhiteSpace représente les chaînes qui ne sont que des espaces ou null / vide.
  2. .Trim () supprime les espaces à l'avant et à l'arrière de la chaîne.
  3. .First () prend le premier caractère d'un ienumerable (ou d'une chaîne).
  4. Nous devons vérifier si c'est une lettre qui peut / devrait être en majuscule.
  5. Nous ajoutons ensuite le reste de la chaîne, uniquement si la longueur indique que nous le devrions.
  6. Selon les meilleures pratiques .Net, nous devrions fournir une culture sous System.Globalization.CultureInfo.
  7. Les fournir en tant que paramètres facultatifs rend cette méthode totalement réutilisable, sans avoir à taper à chaque fois la culture choisie.

    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;
    }
Patrick Knott
la source
2
Bien que cela couvre la plupart des cas, ne serait-il pas plutôt lent compte tenu du nombre de chaînes créées à chaque opération? Il y a une tonne d'allocation de chaînes en cours ici. De préférence, il serait alloué une fois, et une seule fois.
Douglas Gaskell
1

Récemment, j'avais une exigence similaire et je me suis souvenu que la fonction LINQ Select () fournit un index:

string input;
string output;

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

Comme j'en ai besoin très souvent, j'ai créé une méthode d'extension pour le type de chaîne:

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

Veuillez noter que seule la première lettre est convertie en majuscules - tous les caractères restants ne sont pas touchés. Si vous avez besoin que les autres caractères soient en minuscules, vous pouvez également appeler Char.ToLower (currentChar) pour index> 0 ou appeler ToLower () sur la chaîne entière en premier lieu.

En ce qui concerne les performances, j'ai comparé le code avec la solution de Darren. Sur ma machine, le code de Darren est environ 2 fois plus rapide, ce qui n'est pas surprenant puisqu'il n'édite directement que la première lettre d'un tableau de caractères. Je vous suggère donc de prendre le code de Darren si vous avez besoin de la solution la plus rapide disponible. Si vous souhaitez également intégrer d'autres manipulations de chaînes, il peut être pratique d'avoir la puissance expressive d'une fonction lambda touchant les caractères de la chaîne d'entrée - vous pouvez facilement étendre cette fonction - alors je laisse cette solution ici.

Grimm
la source
Je me demandais comment je pouvais résoudre ce problème, j'ai trouvé ma propre solution, puis je suis revenu pour la poster uniquement pour découvrir que vous aviez trouvé exactement la même solution que j'avais déjà. +1 à vous!
BlueFuzzyThing
Merci beaucoup.
Grimm
1

Je pense que la méthode ci-dessous est la meilleure solution

    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

D.JCode
la source
1

Comme cette question concerne la maximisation des performances, j'ai adopté la version de Darren pour utiliser Spans, ce qui réduit les déchets et améliore la vitesse d'environ 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);
        }

Performance

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

Code de test complet

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

}

Edit: il y avait un typeo, au lieu de s [0], il y avait un [0] - cela donne la même valeur vide à la plage allouée a.

Marcell Toth
la source
0

Cela met en majuscule cette première lettre et chaque lettre suivant un espace et les minuscules toute autre lettre.

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;
        }
    }
}
thattolleyguy
la source
1
Ou si vous ne voulez pas écrire de murs de code - CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); fait la même chose.
Chev
Ouais ... je ne savais pas à ce sujet :) Et en raison de mon énorme quantité de code, les réponses de tous les autres sont apparues alors que j'étais encore en train de taper.
thattolleyguy
MISE À JOUR: 1) Une légère différence entre cette réponse et ToTitleCase, c'est que cette réponse force les mots qui sont tous des majuscules à devenir TitleCase, tandis que ToTitleCase laisse ces mots seuls (en supposant qu'ils pourraient être des acronymes). Cela pourrait ou non être ce que l'on souhaite. Un avantage d'avoir un exemple de code comme celui-ci, c'est qu'il peut être modifié comme vous le souhaitez. 2) cela ne gérera pas correctement l'espace blanc autre que ''. devrait remplacer le test à blanc par le test d'espace blanc.
ToolmakerSteve
0

Utilisez le code suivant:

string  strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();
Prashant Banavali
la source
Cela ne vaut même pas la peine que mon représentant retire cette réponse ajoutée des années plus tard, ce qui est évidemment équivalent aux réponses déjà existantes. Si vous souhaitez ajouter une nouvelle réponse à une question contenant de nombreuses réponses, veuillez expliquer ce que vous pensez être supérieur à votre réponse, ou dans quelles circonstances votre réponse serait plus utile que d'autres réponses. Être spécifique.
ToolmakerSteve
0

Il semble qu'aucune des solutions données ici ne traite d'un espace blanc avant la chaîne.

Ajouter juste ceci comme une pensée:

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

Il devrait gérer this won't work on other answers(cette phrase a un espace au début), et si vous n'aimez pas le découpage de l'espace, passez simplement un falsesecond paramètre (ou changez la valeur par défaut en false, et passez truesi vous voulez gérer l'espace)

Noctis
la source
0

Le moyen le plus simple de mettre en majuscule sa première lettre est:

1- Utilisation de Sytem.Globalization;

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

  myTI.ToTitleCase(textboxname.Text)

"

Saad Khalid
la source
1
Cette réponse est essentiellement identique aux réponses données des années plus tôt. Cela n'ajoute rien à la discussion.
ToolmakerSteve
C'est également faux, tout comme le commentaire de l'autre, cela transforme chaque première lettre en tous les mots en majuscules et non en Red House au lieu de Red House.
DeadlyChambers du
0

la fonction suivante est correcte dans tous les cas:

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

J'ai trouvé ça ici


la source
Pourquoi? Pourquoi ajouter une autre réponse alors qu'il y a déjà tant de réponses qui semblent similaires? Quel est le problème avec toutes les réponses existantes, qui vous a incité à en ajouter une autre?
ToolmakerSteve
Parce que cet answare est correct à tous points de vue. Relax.
Je suis désolé; J'étais inutilement sévère. Je m'en tiendrai aux faits: 1) C'est essentiellement la même chose que la réponse de thattolleyguy sept ans plus tôt. 2) Cela a le même défaut que cette réponse: ne gère pas les espaces blancs autres que les caractères vides. 3) Cela répond à une question légèrement différente de celle posée par OP. Utilisez une réponse comme celle-ci si vous voulez que tous les mots soient en majuscule. 4) Habituellement, la manière la plus simple d'y parvenir est d'utiliser TitleInfo.ToTitleCase. (D'un autre côté, un avantage de l'exemple de code est qu'il peut être personnalisé selon vos besoins.)
ToolmakerSteve
Je me corrige: c'est différent de l'approche de thattolleyguy: cela laisse des lettres intactes qui ne sont pas la première lettre du mot. Au lieu de cela, c'est un double de la réponse de zamoldar . Heureusement, bravo à Darian pour avoir donné le lien vers la source - il semble que le zamoldar ait plagié sans donner de crédit. En raison de la fourniture de ce lien source et , partant, de l'amélioration de la discussion , je vote pour cette réponse, malgré mes critiques.
ToolmakerSteve
1
Darian, deux améliorations qui pourraient être apportées: 1) utiliser à la char.IsWhiteSpace( array[ i -1 ] )place de .. == ' ', pour gérer tous les espaces blancs. 2) supprimer les deux endroits qui le font if (char.isLower(..))- ils ne servent à rien. ToUpperne fait tout simplement rien si un caractère n'est pas en minuscules.
ToolmakerSteve
0

En développant la question de Carlos ci-dessus, si vous souhaitez mettre en majuscule plusieurs phrases, vous pouvez utiliser ce code:

    /// <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; 
    }
Zamir
la source
0

Solution possible pour résoudre votre problème.

   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();
   }
sayah imad
la source