Convertissez toutes les premières lettres en majuscules, restez en bas pour chaque mot

110

J'ai une chaîne de texte (environ 5 à 6 mots principalement) que je dois convertir.

Actuellement, le texte ressemble à:

THIS IS MY TEXT RIGHT NOW

Je veux le convertir en:

This Is My Text Right Now

Je peux parcourir ma collection de chaînes, mais je ne sais pas comment procéder pour effectuer cette modification de texte.

mrblah
la source

Réponses:

251
string s = "THIS IS MY TEXT RIGHT NOW";

s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
jspcal
la source
31
Haha vraiment? C'est là que c'est? J'adore .NET mais certains des concepteurs d'API sont de vrais imbéciles.
George Mauer
7
Notez que bien que cette méthode fasse ce que le questionneur a demandé, c'est un algorithme naïf qui ne fait que capitaliser chaque mot, quel que soit le type de mot. Il ne s'agit pas vraiment de "casse du titre" puisque les règles de casse du titre diffèrent selon les langues. Ce n'est même pas correct pour l'anglais. Par exemple, le titre «about a boy» devrait être «About a Boy» en anglais, mais cette méthode donnerait «About A Boy». Si vous voulez une vraie casse de titre, vous devrez écrire votre propre méthode.
Ryan Lundy
18
Je ne les appellerais pas des idiots. Le truc avec "ToTitleCase" est qu'il dépend de la culture, donc il doit être dans l'espace de noms System.Globalization. Passer par CurrentThread est juste fait pour obtenir la culture actuelle du thread (sachez que cela peut entraîner un comportement différent si l'utilisateur a un autre paramètre régional!). Vous pouvez également faire "CultureInfo.InvariantCulture.TextInfo.ToTitleCase ()", ce qui peut être mieux car InvariantCulture se comporte de la même manière sur toutes les cultures. Inutile George: Où mettriez-vous une fonction de chaîne spécifique à la culture?
Michael Stum
3
Notez également les commentaires sur TOUTES les chaînes MAJUSCULES: msdn.microsoft.com/en-us/library/…
Michael Stum
2
la méthode toLower () doit être ToLower (), la première lettre de la méthode commence par des majuscules
Alex
84

Je préfère probablement appeler le ToTitleCase de CultureInfo ( System.Globalization ) que Thread.CurrentThread ( System.Threading )

string s = "THIS IS MY TEXT RIGHT NOW";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

mais cela devrait être la même chose que la solution jspcal

ÉDITER

En fait, ces solutions ne sont pas les mêmes : CurrentThread--calls -> CultureInfo!


System.Threading.Thread.CurrentThread.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Threading.Thread.get_CurrentThread
IL_000B:  callvirt    System.Threading.Thread.get_CurrentCulture
IL_0010:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0015:  ldloc.0     // s
IL_0016:  callvirt    System.String.ToLower
IL_001B:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_0020:  stloc.0     // s

System.Globalization.CultureInfo.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Globalization.CultureInfo.get_CurrentCulture
IL_000B:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0010:  ldloc.0     // s
IL_0011:  callvirt    System.String.ToLower
IL_0016:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_001B:  stloc.0     // s

Références:

Filippo Vitale
la source
16

Il existe plusieurs façons de convertir le premier caractère d'une chaîne en majuscules.

La première méthode consiste à créer une méthode qui met simplement le premier caractère en majuscule et ajoute le reste de la chaîne à l'aide d'une sous-chaîne:

public string UppercaseFirst(string s)
    {
        return char.ToUpper(s[0]) + s.Substring(1);
    }

La deuxième méthode (qui est légèrement plus rapide) consiste à diviser la chaîne en un tableau de caractères, puis à reconstruire la chaîne:

public string UppercaseFirst(string s)
    {
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }
Jamie Dixon
la source
1
Cette solution ne répond pas exactement à la question de manière adéquate. Le titre de la question est "Convertissez toutes les premières lettres en majuscules, restez en bas pour chaque mot". Cependant, cette solution ne met en majuscule que la première lettre de la chaîne entière. Par conséquent, cette solution convertirait «hello world» en «Hello world» plutôt que «Hello World».
brsfan
9

Non testé mais quelque chose comme ça devrait fonctionner:

var phrase = "THIS IS MY TEXT RIGHT NOW";
var rx = new System.Text.RegularExpressions.Regex(@"(?<=\w)\w");
var newString = rx.Replace(phrase,new MatchEvaluator(m=>m.Value.ToLowerInvariant()));

Essentiellement, il dit "préformer une correspondance regex sur toutes les occurrences d'un caractère alphanumérique qui suit un autre caractère alphanumérique, puis le remplacer par une version minuscule de lui-même"

George Mauer
la source
Celui-ci fait également que tous les mots en majuscules commencent par des majuscules et se poursuivent avec des minuscules. Exactement ce que je cherchais.
M. Azyoksul
9

Si vous utilisez sur une page Web, vous pouvez également utiliser CSS:

style="text-transform:capitalize;"

M.Eren Çelik
la source
2
Pourquoi CSS? Quand la question se pose pour c # asp.net regex
Jay
1
La balise ASP.NETmontre que l'OP le fait sur WEB. Bien sûr, ce n'est pas la réponse à la question car OP exigeait la solution C#mais cela résout le problème et peut être une solution alternative. +1
Muhammad Saqib
6

Lorsque la construction de grandes tables est un problème, la deuxième fonction de Jamie Dixon est la meilleure, mais elle ne fonctionne pas complètement telle quelle ...

Il ne parvient pas à mettre toutes les lettres en minuscules et ne met en majuscule que la première lettre de la chaîne, pas la première lettre de chaque mot de la chaîne ... l'option ci-dessous résout les deux problèmes:

    public string UppercaseFirstEach(string s)
    {
        char[] a = s.ToLower().ToCharArray();

        for (int i = 0; i < a.Count(); i++ )
        {
            a[i] = i == 0 || a[i-1] == ' ' ? char.ToUpper(a[i]) : a[i];

        }

        return new string(a);
    }

Bien qu'à ce stade, il n'est pas certain que ce soit toujours l'option la plus rapide, la Regexsolution fournie par George Mauer pourrait être plus rapide ... quelqu'un qui s'en soucie suffisamment devrait la tester.

Serj Sagan
la source
2
cela fonctionne, mais j'ai changé ce "a.Count ()" en a.Length
Christian
2

Je ne sais pas si la solution ci-dessous est plus ou moins efficace que la réponse de jspcal, mais je suis presque sûr qu'elle nécessite moins de création d'objet que celle de Jamie et George.

string s = "THIS IS MY TEXT RIGHT NOW";
StringBuilder sb = new StringBuilder(s.Length);
bool capitalize = true;
foreach (char c in s) {
    sb.Append(capitalize ? Char.ToUpper(c) : Char.ToLower(c));
    capitalize = !Char.IsLetter(c);
}
return sb.ToString();
éphémère
la source
1
Si nous sommes concernés par la création d'objets, pourquoi ne pas le faire sur place avec une indexation de boucle for sur s au lieu d'utiliser un StringBuilder?
jball
0

En plus de la première réponse, n'oubliez pas de modifier l'index de démarrage de la sélection de chaîne à la fin du mot ou vous obtiendrez l'ordre inverse des lettres dans la chaîne.

s.SelectionStart=s.Length;
zia khan
la source
0

Essayez cette technique; Il renvoie le résultat souhaité

CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());

Et n'oubliez pas de l'utiliser System.Globalization.

Au-delà
la source
0

Une des solutions possibles qui pourrait vous intéresser. Traverser un tableau de caractères de droite à gauche et vice versa dans une boucle.

public static string WordsToCapitalLetter(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException("value");
        }

        int inputValueCharLength = value.Length;
        var valueAsCharArray = value.ToCharArray();

        int min = 0;
        int max = inputValueCharLength - 1;

        while (max > min)
        {
            char left = value[min];
            char previousLeft = (min == 0) ? left : value[min - 1];

            char right = value[max];
            char nextRight = (max == inputValueCharLength - 1) ? right : value[max - 1];

            if (char.IsLetter(left) && !char.IsUpper(left) && char.IsWhiteSpace(previousLeft))
            {
                valueAsCharArray[min] = char.ToUpper(left);
            }

            if (char.IsLetter(right) && !char.IsUpper(right) && char.IsWhiteSpace(nextRight))
            {
                valueAsCharArray[max] = char.ToUpper(right);
            }

            min++;
            max--;
        }

        return new string(valueAsCharArray);
    }
RShp
la source
0

réponse de jspcal comme extension de chaîne.

Program.cs

class Program
{
    static void Main(string[] args)
    {
        var myText = "MYTEXT";
        Console.WriteLine(myText.ToTitleCase()); //Mytext
    }
}

StringExtensions.cs

using System;
public static class StringExtensions
{

    public static string ToTitleCase(this string str)
    {
        if (str == null)
            return null;

        return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
    }
}
Joël Wiklund
la source