web-dev-qa-db-fra.com

Faire la première lettre d'une chaîne en majuscule (avec une performance maximale)

J'ai un DetailsView avec un TextBox et je veux les données d'entrée être toujours enregistrées avec le PREMIÈRE LETTRE EN CAPITAL.

Exemple:

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

Comment puis-je atteindre cet objectif en maximisant les performances ?


NOTE:
En se basant sur les réponses et les commentaires sous les réponses, beaucoup de gens pensent que cela pose la question de la capitalisation de 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 TextInfo 'ToTitleCase méthode. (REMARQUE: ces réponses sont incorrectes pour la question posée.)
Voir TextInfo.ToTitleCase doc pour les mises en garde (ne touche pas les mots en majuscules; ils sont considérés comme des acronymes; vous pouvez utiliser des lettres minuscules au milieu de mots qui "ne devrait pas", par exemple "McDonald" => "Mcdonald"; il n’est pas garanti que toutes les subtilités propres à la culture soient gérées (règles de capitalisation).)


NOTE:
La question est ambiguë de savoir si les lettres après le premier doivent être forcées à minuscule . 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 minuscule, recherchez une réponse contenant ToLower, et non contenant ToTitleCase .

395
anon

EDIT: Mise à jour avec une syntaxe plus récente (et une réponse plus correcte), également en tant que méthode d'extension.

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

ANCIENNES 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 oeil à 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 Darren's (Il y a même un point de repère) même si je changerais c'est string.IsNullOrEmpty(s) validation pour lancer une exception, car 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 pour les valeurs valides de la variable Textbox.

493
Carlos Muñoz
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: Cela fait chaque première lettre en majuscule

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

La bonne façon est d'utiliser Culture:

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

Note: Ceci mettra en majuscule chaque mot dans une chaîne, par ex. "maison rouge" -> "maison rouge". La solution réduira également la casse des majuscules dans les mots, par ex. "vieux McDonald" -> "Vieux Mcdonald".

140

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

NOTE: La raison d'utiliser ToCharArray est plus rapide que l'alternative char.ToUpper(s[0]) + s.Substring(1), c'est qu'une seule chaîne est allouée, alors que l'approche Substring alloue une chaîne pour la sous-chaîne, puis une seconde chaîne à composer. le résultat final.


EDIT: Voici à quoi cette approche ressemble, combinée au test initial de CarlosMuñoz a accepté la réponse :

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

Vous pouvez utiliser la "méthode ToTitleCase"

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

cette méthode d'extention résout tous les problèmes de titlecase.

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 Extention

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

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);
    }
31
Kobi
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}
11
Taras Alenin

Si l'utilisation des performances/de la mémoire pose problème, celle-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;
}
6
Daniel Halan

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 sous la forme d'un tableau Char, et le type Char n'a pas de méthode ToUpper ().

4
Víctor García

Essaye ça:

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

Voici un moyen de le faire en tant que 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 s'appeler 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);
}
3
bingles

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

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 ça aide !!

3
student

Étant donné que je travaillais également sur ce projet et que je cherchais des idées, voici la solution à laquelle je suis arrivé. 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 créer.

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 cela un peu.

3
CAOakley

Cela le fera bien que cela garantira également qu’il n’y ait pas de chapiteaux errants qui ne se trouvent pas au début de la Parole.

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

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 null, vide ou un espace, 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.

2
Stephen Kennedy

Je voulais fournir une réponse "PERFORMANCE MAXIMALE". Dans mon esprit, une réponse "MAXIMUM PERFORMANCE" intercepte tous les scénarios et fournit la réponse à la question prise en compte pour ces scénarios. Donc, voici ma réponse. Pour ces raisons:

  1. IsNullOrWhiteSpace comptes pour les chaînes qui ne sont que des espaces ou null/empty.
  2. .Trim () supprime les espaces au début et à la fin de la chaîne.
  3. .First () prend le premier caractère d'un umerumer (ou chaîne).
  4. Nous devrions 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 devrions le faire.
  6. Selon les meilleures pratiques .Net, nous devrions fournir une culture sous System.Globalization.CultureInfo.
  7. Leur utilisation en tant que paramètres facultatifs rend cette méthode totalement réutilisable, sans avoir à saisir la culture choisie à chaque fois.

    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;
    }
    
1
Patrick Knott

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

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

Le moyen le plus simple de capitaliser la première lettre est:

1- Utiliser System.Globalization;

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

  myTI.ToTitleCase(textboxname.Text)

`

0
Saad Khalid

On dirait qu'aucune des solutions données ici ne traitera d'un espace blanc avant la chaîne.

Il suffit d'ajouter 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 doit gérer this won't work on other answers (cette phrase a un espace au début), et si vous n’aimez pas le rognage d’espace, il suffit de passer un false comme second paramètre (ou de changer le paramètre par défaut en false, et passez true si vous voulez gérer l’espace)

0
Noctis
0
Dinis Cruz

Cette majuscule cette première lettre et chaque lettre suivant un espace et minuscule 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;
        }
    }
}
0
thattolleyguy

tilisez le code suivant:

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

la fonction suivante est correcte pour toutes les manières:

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é que ici

0
Dari

Récemment, j'avais une exigence similaire et je me suis rappelé 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 majuscule - tous les caractères restants ne sont pas touchés. Si vous souhaitez 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, car 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îne, il peut être pratique de disposer du pouvoir expressif d'une fonction lambda touchant les caractères de la chaîne d'entrée. Vous pouvez facilement étendre cette fonction. Je laisse donc cette solution ici.

0
Grimm

En développant la question de Carlos ci-dessus, si vous souhaitez mettre plusieurs phrases en majuscule, utilisez 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; 
    }
0
Zamir

C'est le moyen le plus rapide:

public static unsafe void ToUpperFirst(this string str)
{
    if (str == null) return;
    fixed (char* ptr = str) 
        *ptr = char.ToUpper(*ptr);
}

Sans changer la chaîne d'origine:

public static unsafe string ToUpperFirst(this string str)
{
    if (str == null) return null;
    string ret = string.Copy(str);
    fixed (char* ptr = ret) 
        *ptr = char.ToUpper(*ptr);
    return ret;
}
0
Anonymous