Conversione di stringhe in maiuscolo / minuscolo


300

Ho una stringa che contiene parole in una combinazione di caratteri maiuscoli e minuscoli.

Per esempio: string myData = "a Simple string";

Devo convertire il primo carattere di ogni parola (separato da spazi) in maiuscolo. Quindi voglio il risultato come:string myData ="A Simple String";

C'è un modo semplice per farlo? Non voglio dividere la stringa e fare la conversione (sarà la mia ultima risorsa). Inoltre, è garantito che le stringhe siano in inglese.


1
http://support.microsoft.com/kb/312890 - Come convertire le stringhe in maiuscolo, minuscolo o titolo (corretto) utilizzando Visual C #
ttarchala,

Risposte:


538

MSDN: TextInfo.ToTitleCase

Assicurati di includere: 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

37
Vero. Inoltre, se una parola è tutta in maiuscolo, non funziona. ad esempio - "un agente dell'FBI ha sparato al mio cane" -> "Un agente dell'FBI ha sparato al mio cane". E non gestisce "McDonalds", e così via.
Kobi,

5
@Kirschstein questa funzione fa conver queste parole a caso il titolo, anche se non dovrebbero essere in inglese. Vedere la documentazione: Actual result: "War And Peace".
Kobi,

5
@simbolo - In effetti ho parlato di questo in un commento ... Puoi usare qualcosa del genere text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());, ma è tutt'altro che perfetto. Ad esempio, non gestisce ancora virgolette o parentesi - "(one two three)"-> "(one Two Three)". Potresti voler fare una nuova domanda dopo aver capito esattamente cosa vuoi fare con questi casi.
Kobi,

17
Per qualche motivo quando ho "DR" non diventa "Dr" a meno che non chiami .ToLower () prima di chiamare ToTitleCase () ... Quindi è qualcosa a cui fare attenzione ...
Tod Thomson

16
Un .ToLower () per inserire una stringa è necessario se il testo di input è in maiuscolo
Puneet Ghanshani,

137

Prova questo:

string myText = "a Simple string";

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

Come è già stato sottolineato, l'utilizzo di TextInfo.ToTitleCase potrebbe non fornire i risultati esatti desiderati. Se hai bisogno di un maggiore controllo sull'output, potresti fare qualcosa del genere:

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

E poi usalo così:

var asTitleCase = new string( CharsToTitleCase(myText).ToArray() );

1
Ho provato diverse varianti dell'oggetto TextInfo - nessun errore ma la stringa originale (maiuscola) non è mai stata aggiornata. Ho inserito questo metodo e sono molto grato.
JustSteve,

6
@justSteve, da MSDN ( msdn.microsoft.com/en-us/library/… ): "Tuttavia, questo metodo attualmente non fornisce un involucro adeguato per convertire una parola interamente maiuscola, come un acronimo" - probabilmente dovresti solo ToLower () prima (so che è vecchio, ma nel caso in cui qualcun altro si imbatti in esso e si
chieda

Disponibile solo per .NET Framework 4.7.2 <= frame work <= .NET Core 2.0
Paul Gorbas

70

Ancora un'altra variazione. Sulla base di diversi suggerimenti qui l'ho ridotto a questo metodo di estensione, che funziona benissimo per i miei scopi:

public static string ToTitleCase(this string s) =>
    CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s.ToLower());

8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); sarebbe una soluzione migliore in realtà!
Puneet Ghanshani,

Disponibile solo per .NET Framework 4.7.2 <= frame work <= .NET Core 2.0
Paul Gorbas

Poiché stiamo usando InvariantCulture per TitleCasing, s.ToLowerInvariant () dovrebbe essere usato al posto di s.ToLower ().
Vinigas,

27

Personalmente ho provato il TextInfo.ToTitleCasemetodo, ma non capisco perché non funziona quando tutti i caratteri sono maiuscoli.

Anche se mi piace la funzione util fornita da Winston Smith , lasciami fornire la funzione che sto attualmente usando:

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

Giocare con alcune stringhe di test :

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

Dare output :

|Converting String To Title Case In C#|
|C|
||
|   |
||

1
@harsh: soluzione "brutta" direi ... non ha senso per me che devi prima convertire l'intera stringa in lettere minuscole.
Luis Quijada,

4
È intenzionale, perché se chiedi, per esempio, che "UNICEF e beneficenza" vengano inseriti nel titolo, non vuoi che venga cambiato in Unicef.
Casey,

4
Quindi, invece di chiamare ToLower()l'intera stringa, preferiresti fare tutto ciò da solo e chiamare la stessa funzione su ogni singolo carattere? Non solo è una brutta soluzione, sta dando zero benefici e richiederebbe anche più tempo della funzione integrata.
Krillgar,

3
rest = words[i].Substring(1).ToLower();
Krillgar,

1
@ruffin No. La sottostringa con un singolo parametro int inizia dall'indice indicato e restituisce tutto alla fine della stringa.
Krillgar,

21

Di recente ho trovato una soluzione migliore.

Se il testo contiene tutte le lettere in maiuscolo, TextInfo non lo convertirà nel caso corretto. Possiamo risolverlo usando la funzione minuscola all'interno in questo modo:

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

Ora questo convertirà tutto ciò che entra in Propercase.


17
public static string PropCase(string strText)
{
    return new CultureInfo("en").TextInfo.ToTitleCase(strText.ToLower());
}

1
Mi piace che tu abbia aggiunto ToLower prima di ToTitleCase, copre la situazione in cui il testo di input è tutto maiuscolo.
joelc

7

Se qualcuno è interessato alla soluzione per Compact Framework:

return String.Join(" ", thestring.Split(' ').Select(i => i.Substring(0, 1).ToUpper() + i.Substring(1).ToLower()).ToArray());

Con l'interpolazione della stringa: return string.Join ("", text.Split ('') .Select (i => $ "{i.Substring (0, 1) .ToUpper ()} {i.Substring (1). ToLower ()} ") .ToArray ());
Ted

6

Ecco la soluzione per quel problema ...

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
string txt = textInfo.ToTitleCase(txt);

5

Usa ToLower()prima, che CultureInfo.CurrentCulture.TextInfo.ToTitleCasesul risultato per ottenere l'output corretto.

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

3

Avevo bisogno di un modo per gestire tutte le parole maiuscole e mi piaceva la soluzione di Ricky AH, ma ho fatto un ulteriore passo avanti per implementarla come metodo di estensione. Questo evita il passaggio di dover creare il tuo array di caratteri, quindi chiamare ToArray su di esso in modo esplicito ogni volta, così puoi semplicemente chiamarlo sulla stringa, in questo modo:

utilizzo:

string newString = oldString.ToProper();

codice:

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

}

1
Ho appena aggiunto un'altra condizione OR se (c == '' || c == '\' ') ... a volte i nomi contengono apostrofi (').
JSK,

2

È meglio capire provando il tuo codice ...

Leggi di più

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

1) Converti una stringa in maiuscolo

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

2) Converti una stringa in minuscolo

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

3) Convertire una stringa in TitleCase

    CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
    TextInfo textInfo = cultureInfo.TextInfo;
    string txt = textInfo.ToTitleCase(TextBox1.Text());

1

Ecco un'implementazione, carattere per carattere. Dovrebbe funzionare con "(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);
}

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

1

È possibile modificare direttamente il testo o la stringa in modo corretto utilizzando questo semplice metodo, dopo aver verificato la presenza di valori di stringa nulli o vuoti per eliminare gli errori:

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

0

Prova questo:

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


Chiamare questo metodo nell'evento TextChanged di TextBox.


0

Ho usato i riferimenti sopra e la soluzione completa è: -

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

// È necessario un risultato come "Infoa2z significa tutte le informazioni"
// È necessario convertire anche la stringa in minuscolo, altrimenti non funziona correttamente.

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#


0

Questo è quello che uso e funziona nella maggior parte dei casi, a meno che l'utente non decida di sovrascriverlo premendo Maiusc o Blocco maiuscole. Come su tastiere Android e 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

0

Per quelli che stanno cercando di farlo automaticamente alla pressione dei tasti, l'ho fatto con il seguente codice in vb.net su un controllo di casella di testo personalizzato - puoi ovviamente farlo anche con una normale casella di testo - ma mi piace la possibilità di aggiungere codice ricorrente per controlli specifici tramite controlli personalizzati si adatta al concetto di OOP.

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

0

Funziona bene anche con custodia per cammello: '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();
    }
}

0

Come metodo di estensione:

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

Uso:

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

Risultato:

Kebab Is Deliciou's ;d C...


0

Alternativa con riferimento a Microsoft.VisualBasic(gestisce anche stringhe maiuscole):

string properCase = Strings.StrConv(str, VbStrConv.ProperCase);

0

Senza usare 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())));

Passa attraverso ogni lettera di ogni parola, convertendola in maiuscolo se è la prima lettera altrimenti convertendola in minuscolo.


-1

So che questa è una vecchia domanda ma stavo cercando la stessa cosa per C e l'ho capito, quindi ho pensato di pubblicarlo se qualcun altro sta cercando un modo in 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;
}
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.