Conversion d'une chaîne en casse de titre

300

J'ai une chaîne qui contient des mots dans un mélange de caractères majuscules et minuscules.

Par exemple: string myData = "a Simple string";

J'ai besoin de convertir le premier caractère de chaque mot (séparé par des espaces) en majuscules. Je veux donc le résultat comme:string myData ="A Simple String";

Existe-t-il un moyen simple de procéder? Je ne veux pas diviser la chaîne et faire la conversion (ce sera mon dernier recours). De plus, il est garanti que les chaînes sont en anglais.

Naveen
la source
1
http://support.microsoft.com/kb/312890 - Comment convertir des chaînes en minuscules, majuscules ou titre (approprié) en utilisant Visual C #
ttarchala

Réponses:

538

MSDN: TextInfo.ToTitleCase

Assurez-vous d'inclure: using System.Globalization

string title = "war and peace";

TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;

title = textInfo.ToTitleCase(title); 
Console.WriteLine(title) ; //War And Peace

//When text is ALL UPPERCASE...
title = "WAR AND PEACE" ;

title = textInfo.ToTitleCase(title); 
Console.WriteLine(title) ; //WAR AND PEACE

//You need to call ToLower to make it work
title = textInfo.ToTitleCase(title.ToLower()); 
Console.WriteLine(title) ; //War And Peace
Kobi
la source
37
Vrai. De plus, si un mot est entièrement en majuscules, cela ne fonctionne pas. par exemple - "Un agent du FBI a tiré sur mon chien" -> "Un agent du FBI a tiré sur mon chien". Et il ne gère pas les «McDonalds», etc.
Kobi
5
@Kirschstein cette fonction ne Conver ces mots à titre de cas, même si elles ne devraient pas être en anglais. Consultez la documentation: Actual result: "War And Peace".
Kobi
5
@simbolo - Je ne l'ai pas mentionné dans un commentaire ... Vous pouvez utiliser quelque chose comme ça text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());, mais c'est loin d'être parfait. Par exemple, il ne gère toujours pas les guillemets ou les parenthèses - "(one two three)"-> "(one Two Three)". Vous voudrez peut-être poser une nouvelle question après avoir compris exactement ce que vous voulez faire avec ces cas.
Kobi
17
Pour une raison quelconque, lorsque j'ai "DR", il ne devient pas "Dr" à moins que j'appelle .ToLower () avant d'appeler ToTitleCase () ... C'est donc quelque chose à surveiller ...
Tod Thomson
16
Un .ToLower () pour saisir une chaîne est requis si le texte d'entrée est en majuscules
Puneet Ghanshani
137

Essaye ça:

string myText = "a Simple string";

string asTitleCase =
    System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.
    ToTitleCase(myText.ToLower());

Comme cela a déjà été souligné, l'utilisation de TextInfo.ToTitleCase peut ne pas vous donner les résultats exacts souhaités. Si vous avez besoin de plus de contrôle sur la sortie, vous pouvez faire quelque chose comme ceci:

IEnumerable<char> CharsToTitleCase(string s)
{
    bool newWord = true;
    foreach(char c in s)
    {
        if(newWord) { yield return Char.ToUpper(c); newWord = false; }
        else yield return Char.ToLower(c);
        if(c==' ') newWord = true;
    }
}

Et puis utilisez-le comme ceci:

var asTitleCase = new string( CharsToTitleCase(myText).ToArray() );
Winston Smith
la source
1
J'ai essayé plusieurs variantes de l'objet TextInfo - aucune erreur mais la chaîne d'origine (majuscule) n'a jamais été mise à jour. Branché cette méthode et je suis très reconnaissant.
justSteve
6
@justSteve, de MSDN ( msdn.microsoft.com/en-us/library/… ): "Cependant, cette méthode ne fournit pas actuellement de casse appropriée pour convertir un mot entièrement en majuscules, comme un acronyme" - vous devriez probablement juste ToLower () d'abord (je sais que c'est vieux, mais juste au cas où quelqu'un d'autre tomberait dessus et se demander pourquoi!)
nizmow
Uniquement disponible pour .NET Framework 4.7.2 <= votre travail de cadre <= .NET Core 2.0
Paul Gorbas
70

Encore une autre variation. Sur la base de plusieurs conseils ici, je l'ai réduit à cette méthode d'extension, qui fonctionne très bien à mes fins:

public static string ToTitleCase(this string s) =>
    CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s.ToLower());
Todd Menier
la source
8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); serait un meilleur ajustement en fait!
Puneet Ghanshani
Uniquement disponible pour .NET Framework 4.7.2 <= votre travail de cadre <= .NET Core 2.0
Paul Gorbas
Puisque nous utilisons InvariantCulture pour TitleCasing, s.ToLowerInvariant () doit être utilisé à la place de s.ToLower ().
Vinigas
27

Personnellement, j'ai essayé la TextInfo.ToTitleCaseméthode, mais je ne comprends pas pourquoi cela ne fonctionne pas lorsque tous les caractères sont en majuscules.

Bien que j'aime la fonction util fournie par Winston Smith , permettez-moi de fournir la fonction que j'utilise actuellement:

public static String TitleCaseString(String s)
{
    if (s == null) return s;

    String[] words = s.Split(' ');
    for (int i = 0; i < words.Length; i++)
    {
        if (words[i].Length == 0) continue;

        Char firstChar = Char.ToUpper(words[i][0]); 
        String rest = "";
        if (words[i].Length > 1)
        {
            rest = words[i].Substring(1).ToLower();
        }
        words[i] = firstChar + rest;
    }
    return String.Join(" ", words);
}

Jouer avec certaines chaînes de tests :

String ts1 = "Converting string to title case in C#";
String ts2 = "C";
String ts3 = "";
String ts4 = "   ";
String ts5 = null;

Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts1)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts2)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts3)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts4)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts5)));

Donner une sortie :

|Converting String To Title Case In C#|
|C|
||
|   |
||
Luis Quijada
la source
1
@harsh: solution "laide", je dirais ... n'a aucun sens pour moi que vous devez d'abord convertir la chaîne entière en minuscules.
Luis Quijada
4
C'est intentionnel, parce que si vous demandez, par exemple, "l'UNICEF et la charité" pour le titre, vous ne voulez pas qu'il soit changé pour l'Unicef.
Casey
4
Donc, au lieu d'appeler ToLower()la chaîne entière, vous préférez faire tout cela vous-même et appeler la même fonction sur chaque caractère individuel? Non seulement c'est une solution laide, elle n'apporte aucun avantage et prendrait même plus de temps que la fonction intégrée.
krillgar
3
rest = words[i].Substring(1).ToLower();
krillgar
1
@ruffin No. La sous- chaîne avec un seul paramètre int commence à l'index donné et renvoie tout à la fin de la chaîne.
krillgar
21

Récemment, j'ai trouvé une meilleure solution.

Si votre texte contient toutes les lettres en majuscules, TextInfo ne les convertira pas dans la casse appropriée. Nous pouvons résoudre ce problème en utilisant la fonction minuscule à l'intérieur comme ceci:

public static string ConvertTo_ProperCase(string text)
{
    TextInfo myTI = new CultureInfo("en-US", false).TextInfo;
    return myTI.ToTitleCase(text.ToLower());
}

Maintenant, cela convertira tout ce qui entre dans Propercase.

Binod
la source
17
public static string PropCase(string strText)
{
    return new CultureInfo("en").TextInfo.ToTitleCase(strText.ToLower());
}
Rajesh
la source
1
J'aime que vous ayez ajouté le ToLower avant ToTitleCase, couvre la situation où le texte d'entrée est tout en majuscules.
joelc
7

Si quelqu'un est intéressé par la solution pour Compact Framework:

return String.Join(" ", thestring.Split(' ').Select(i => i.Substring(0, 1).ToUpper() + i.Substring(1).ToLower()).ToArray());
Mibou
la source
Avec l'interpolation de chaîne: retourne string.Join ("", text.Split ('') .Select (i => $ "{i.Substring (0, 1) .ToUpper ()} {i.Substring (1). ToLower ()} ") .ToArray ());
Ted
6

Voici la solution à ce problème ...

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
string txt = textInfo.ToTitleCase(txt);
Jade
la source
5

Utilisez d' ToLower()abord, puis CultureInfo.CurrentCulture.TextInfo.ToTitleCasesur le résultat pour obtenir la sortie correcte.

    //---------------------------------------------------------------
    // Get title case of a string (every word with leading upper case,
    //                             the rest is lower case)
    //    i.e: ABCD EFG -> Abcd Efg,
    //         john doe -> John Doe,
    //         miXEd CaSING - > Mixed Casing
    //---------------------------------------------------------------
    public static string ToTitleCase(string str)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
    }
DDan
la source
3

J'avais besoin d'un moyen de gérer tous les mots en majuscules et j'aimais la solution de Ricky AH, mais je suis allé plus loin pour l'implémenter comme méthode d'extension. Cela évite de devoir créer votre tableau de caractères, puis d'appeler ToArray explicitement à chaque fois - vous pouvez donc simplement l'appeler sur la chaîne, comme ceci:

usage:

string newString = oldString.ToProper();

code:

public static class StringExtensions
{
    public static string ToProper(this string s)
    {
        return new string(s.CharsToTitleCase().ToArray());
    }

    public static IEnumerable<char> CharsToTitleCase(this string s)
    {
        bool newWord = true;
        foreach (char c in s)
        {
            if (newWord) { yield return Char.ToUpper(c); newWord = false; }
            else yield return Char.ToLower(c);
            if (c == ' ') newWord = true;
        }
    }

}
Adam Diament
la source
1
Je viens d'ajouter une condition OR supplémentaire si (c == '' || c == '\' ') ... parfois les noms contiennent des apostrophes (').
JSK
2

Il vaut mieux le comprendre en essayant votre propre code ...

Lire la suite

http://www.stupidcodes.com/2014/04/convert-string-to-uppercase-proper-case.html

1) Convertir une chaîne en majuscules

string lower = "converted from lowercase";
Console.WriteLine(lower.ToUpper());

2) Convertir une chaîne en minuscules

string upper = "CONVERTED FROM UPPERCASE";
Console.WriteLine(upper.ToLower());

3) Convertir une chaîne en TitleCase

    CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
    TextInfo textInfo = cultureInfo.TextInfo;
    string txt = textInfo.ToTitleCase(TextBox1.Text());
Sunil Acharya
la source
1

Voici une implémentation, caractère par caractère. Devrait fonctionner avec "(One Two Three)"

public static string ToInitcap(this string str)
{
    if (string.IsNullOrEmpty(str))
        return str;
    char[] charArray = new char[str.Length];
    bool newWord = true;
    for (int i = 0; i < str.Length; ++i)
    {
        Char currentChar = str[i];
        if (Char.IsLetter(currentChar))
        {
            if (newWord)
            {
                newWord = false;
                currentChar = Char.ToUpper(currentChar);
            }
            else
            {
                currentChar = Char.ToLower(currentChar);
            }
        }
        else if (Char.IsWhiteSpace(currentChar))
        {
            newWord = true;
        }
        charArray[i] = currentChar;
    }
    return new string(charArray);
}
Jeson Martajaya
la source
1
String TitleCaseString(String s)
{
    if (s == null || s.Length == 0) return s;

    string[] splits = s.Split(' ');

    for (int i = 0; i < splits.Length; i++)
    {
        switch (splits[i].Length)
        {
            case 1:
                break;

            default:
                splits[i] = Char.ToUpper(splits[i][0]) + splits[i].Substring(1);
                break;
        }
    }

    return String.Join(" ", splits);
}
varun sharma
la source
1

Vous pouvez directement changer le texte ou la chaîne en utilisant cette méthode simple, après avoir vérifié les valeurs de chaîne nulles ou vides afin d'éliminer les erreurs:

public string textToProper(string text)
{
    string ProperText = string.Empty;
    if (!string.IsNullOrEmpty(text))
    {
        ProperText = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text);
    }
    else
    {
        ProperText = string.Empty;
    }
    return ProperText;
}
Ashraf Abusada
la source
0

Essaye ça:

using System.Globalization;
using System.Threading;
public void ToTitleCase(TextBox TextBoxName)
        {
            int TextLength = TextBoxName.Text.Length;
            if (TextLength == 1)
            {
                CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
                TextInfo textInfo = cultureInfo.TextInfo;
                TextBoxName.Text = textInfo.ToTitleCase(TextBoxName.Text);
                TextBoxName.SelectionStart = 1;
            }
            else if (TextLength > 1 && TextBoxName.SelectionStart < TextLength)
            {
                int x = TextBoxName.SelectionStart;
                CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
                TextInfo textInfo = cultureInfo.TextInfo;
                TextBoxName.Text = textInfo.ToTitleCase(TextBoxName.Text);
                TextBoxName.SelectionStart = x;
            }
            else if (TextLength > 1 && TextBoxName.SelectionStart >= TextLength)
            {
                CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
                TextInfo textInfo = cultureInfo.TextInfo;
                TextBoxName.Text = textInfo.ToTitleCase(TextBoxName.Text);
                TextBoxName.SelectionStart = TextLength;
            }
        }


Appelez cette méthode dans l'événement TextChanged de TextBox.

krishna
la source
0

J'ai utilisé les références ci-dessus et la solution complète est: -

Use Namespace System.Globalization;
string str="INFOA2Z means all information";

// Besoin d'un résultat comme "Infoa2z signifie toutes les informations"
// Nous devons également convertir la chaîne en minuscules, sinon elle ne fonctionne pas correctement.

TextInfo ProperCase= new CultureInfo("en-US", false).TextInfo;

str= ProperCase.ToTitleCase(str.toLower());

http://www.infoa2z.com/asp.net/change-string-to-proper-case-in-an-asp.net-using-c#

Rakesh Dhiman
la source
0

C'est ce que j'utilise et cela fonctionne dans la plupart des cas, sauf si l'utilisateur décide de le remplacer en appuyant sur Maj ou sur le verrouillage des majuscules. Comme sur les claviers Android et iOS.

Private Class ProperCaseHandler
    Private Const wordbreak As String = " ,.1234567890;/\-()#$%^&*€!~+=@"
    Private txtProperCase As TextBox

    Sub New(txt As TextBox)
        txtProperCase = txt
        AddHandler txt.KeyPress, AddressOf txtTextKeyDownProperCase
    End Sub

    Private Sub txtTextKeyDownProperCase(ByVal sender As System.Object, ByVal e As Windows.Forms.KeyPressEventArgs)
        Try
            If Control.IsKeyLocked(Keys.CapsLock) Or Control.ModifierKeys = Keys.Shift Then
                Exit Sub
            Else
                If txtProperCase.TextLength = 0 Then
                    e.KeyChar = e.KeyChar.ToString.ToUpper()
                    e.Handled = False
                Else
                    Dim lastChar As String = txtProperCase.Text.Substring(txtProperCase.SelectionStart - 1, 1)

                    If wordbreak.Contains(lastChar) = True Then
                        e.KeyChar = e.KeyChar.ToString.ToUpper()
                        e.Handled = False
                    End If
                End If

            End If

        Catch ex As Exception
            Exit Sub
        End Try
    End Sub
End Class
Dasith Wijes
la source
0

Pour ceux qui cherchent à le faire automatiquement en appuyant sur une touche, je l'ai fait avec le code suivant sur vb.net sur une zone de texte personnalisée - vous pouvez évidemment le faire également avec une zone de texte normale - mais j'aime la possibilité d'ajouter du code récurrent pour des contrôles spécifiques via des commandes personnalisées, il convient au concept de POO.

Imports System.Windows.Forms
Imports System.Drawing
Imports System.ComponentModel

Public Class MyTextBox
    Inherits System.Windows.Forms.TextBox
    Private LastKeyIsNotAlpha As Boolean = True
    Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
        If _ProperCasing Then
            Dim c As Char = e.KeyChar
            If Char.IsLetter(c) Then
                If LastKeyIsNotAlpha Then
                    e.KeyChar = Char.ToUpper(c)
                    LastKeyIsNotAlpha = False
                End If
            Else
                LastKeyIsNotAlpha = True
            End If
        End If
        MyBase.OnKeyPress(e)
End Sub
    Private _ProperCasing As Boolean = False
    <Category("Behavior"), Description("When Enabled ensures for automatic proper casing of string"), Browsable(True)>
    Public Property ProperCasing As Boolean
        Get
            Return _ProperCasing
        End Get
        Set(value As Boolean)
            _ProperCasing = value
        End Set
    End Property
End Class
Andre Gotlieb
la source
0

Fonctionne bien même avec un étui à chameau: 'someText in YourPage'

public static class StringExtensions
{
    /// <summary>
    /// Title case example: 'Some Text In Your Page'.
    /// </summary>
    /// <param name="text">Support camel and title cases combinations: 'someText in YourPage'</param>
    public static string ToTitleCase(this string text)
    {
        if (string.IsNullOrEmpty(text))
        {
            return text;
        }
        var result = string.Empty;
        var splitedBySpace = text.Split(new[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries);
        foreach (var sequence in splitedBySpace)
        {
            // let's check the letters. Sequence can contain even 2 words in camel case
            for (var i = 0; i < sequence.Length; i++)
            {
                var letter = sequence[i].ToString();
                // if the letter is Big or it was spaced so this is a start of another word
                if (letter == letter.ToUpper() || i == 0)
                {
                    // add a space between words
                    result += ' ';
                }
                result += i == 0 ? letter.ToUpper() : letter;
            }
        }            
        return result.Trim();
    }
}
Igor
la source
0

Comme méthode d'extension:

/// <summary>
//     Returns a copy of this string converted to `Title Case`.
/// </summary>
/// <param name="value">The string to convert.</param>
/// <returns>The `Title Case` equivalent of the current string.</returns>
public static string ToTitleCase(this string value)
{
    string result = string.Empty;

    for (int i = 0; i < value.Length; i++)
    {
        char p = i == 0 ? char.MinValue : value[i - 1];
        char c = value[i];

        result += char.IsLetter(c) && ((p is ' ') || p is char.MinValue) ? $"{char.ToUpper(c)}" : $"{char.ToLower(c)}";
    }

    return result;
}

Usage:

"kebab is DELICIOU's   ;d  c...".ToTitleCase();

Résultat:

Kebab Is Deliciou's ;d C...

Ricky espagnol
la source
0

Alternative en référence à Microsoft.VisualBasic(gère également les chaînes majuscules):

string properCase = Strings.StrConv(str, VbStrConv.ProperCase);
Slai
la source
0

Sans utiliser TextInfo:

public static string TitleCase(this string text, char seperator = ' ') =>
  string.Join(seperator, text.Split(seperator).Select(word => new string(
    word.Select((letter, i) => i == 0 ? char.ToUpper(letter) : char.ToLower(letter)).ToArray())));

Il parcourt chaque lettre de chaque mot, le convertissant en majuscule s'il s'agit de la première lettre, sinon le convertissant en minuscule.

facepalm42
la source
-1

Je sais que c'est une vieille question mais je cherchais la même chose pour C et je l'ai compris alors j'ai pensé que je le posterais si quelqu'un d'autre cherche un moyen en C:

char proper(char string[]){  

int i = 0;

for(i=0; i<=25; i++)
{
    string[i] = tolower(string[i]);  //converts all character to lower case
    if(string[i-1] == ' ') //if character before is a space 
    {
        string[i] = toupper(string[i]); //converts characters after spaces to upper case
    }

}
    string[0] = toupper(string[0]); //converts first character to upper case


    return 0;
}
Daveythewavey19
la source