Convertir cadena a mayúscula

300

Tengo una cadena que contiene palabras en una mezcla de mayúsculas y minúsculas.

Por ejemplo: string myData = "a Simple string";

Necesito convertir el primer carácter de cada palabra (separado por espacios) en mayúsculas. Entonces quiero el resultado como:string myData ="A Simple String";

¿Hay alguna manera fácil de hacer esto? No quiero dividir la cadena y hacer la conversión (ese será mi último recurso). Además, se garantiza que las cadenas están en inglés.

Naveen
fuente
1
http://support.microsoft.com/kb/312890 - Cómo convertir cadenas a minúsculas, mayúsculas o mayúsculas o minúsculas utilizando Visual C #
ttarchala

Respuestas:

538

MSDN: TextInfo.ToTitleCase

Asegúrese de incluir: 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
fuente
37
Cierto. Además, si una palabra es mayúscula, no funciona. por ejemplo, "un agente del FBI le disparó a mi PERRO" -> "Un agente del FBI le disparó a mi PERRO". Y no maneja "McDonalds", y así sucesivamente.
Kobi el
55
@Kirschstein esta función hace conver estas palabras a mayúsculas, a pesar de que no deben estar en Inglés. Consulte la documentación: Actual result: "War And Peace".
Kobi el
55
@simbolo - Realmente lo mencioné en un comentario ... Puedes usar algo como text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());, pero está lejos de ser perfecto. Por ejemplo, todavía no maneja comillas o paréntesis - "(one two three)"-> "(one Two Three)". Es posible que desee hacer una nueva pregunta después de averiguar exactamente qué quiere hacer con estos casos.
Kobi
17
Por alguna razón, cuando tengo "DR" no se convierte en "Dr" a menos que llame a .ToLower () antes de llamar a ToTitleCase () ... Así que eso es algo a tener en cuenta ...
Tod Thomson
16
Se requiere un .ToLower () para ingresar la cadena si el texto de entrada está en mayúscula
Puneet Ghanshani
137

Prueba esto:

string myText = "a Simple string";

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

Como ya se ha señalado, el uso de TextInfo.ToTitleCase podría no proporcionarle los resultados exactos que desea. Si necesita más control sobre la salida, puede hacer algo como esto:

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

Y luego úsalo así:

var asTitleCase = new string( CharsToTitleCase(myText).ToArray() );
Winston Smith
fuente
1
Intenté varias variaciones del objeto TextInfo, sin errores, pero la cadena original (mayúscula) nunca se actualizó. Conecté este método y estoy muy agradecido.
justSteve
66
@justSteve, de MSDN ( msdn.microsoft.com/en-us/library/… ): "Sin embargo, este método actualmente no proporciona una carcasa adecuada para convertir una palabra que está completamente en mayúscula, como un acrónimo" - probablemente debería solo ToLower () primero (sé que esto es viejo, pero por si alguien más se topa con él y se pregunta por qué)
nizmow
Solo disponible para .NET Framework 4.7.2 <= su marco de trabajo <= .NET Core 2.0
Paul Gorbas
70

Otra variación más. Basado en varios consejos aquí, lo he reducido a este método de extensión, que funciona muy bien para mis propósitos:

public static string ToTitleCase(this string s) =>
    CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s.ToLower());
Todd Menier
fuente
8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); sería un mejor ajuste en realidad!
Puneet Ghanshani
Solo disponible para .NET Framework 4.7.2 <= su marco de trabajo <= .NET Core 2.0
Paul Gorbas
Como estamos usando InvariantCulture para TitleCasing, se debe usar s.ToLowerInvariant () en lugar de s.ToLower ().
Vinigas
27

Personalmente probé el TextInfo.ToTitleCasemétodo, pero no entiendo por qué no funciona cuando todos los caracteres están en mayúsculas.

Aunque me gusta la función util proporcionada por Winston Smith , permítame proporcionar la función que estoy usando actualmente:

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

Jugando con algunas cadenas de prueba :

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

Dando salida :

|Converting String To Title Case In C#|
|C|
||
|   |
||
Luis Quijada
fuente
1
@harsh: diría que la solución "fea" ... no tiene sentido para mí que primero tengas que convertir toda la cadena a minúsculas.
Luis Quijada
44
Es intencional, porque si solicita, digamos, "UNICEF y la caridad" para ser titulado, no quiere que se cambie a Unicef.
Casey
44
Entonces, en lugar de invocar ToLower()la cadena completa, ¿preferiría hacer todo ese trabajo usted mismo y llamar a la misma función en cada carácter individual? No solo es una solución fea, está dando cero beneficios, e incluso tomaría más tiempo que la función incorporada.
krillgar
3
rest = words[i].Substring(1).ToLower();
krillgar
1
@ruffin No. La subcadena con un único parámetro int comienza en el índice dado y devuelve todo al final de la cadena.
krillgar
21

Recientemente encontré una mejor solución.

Si su texto contiene todas las letras en mayúscula, TextInfo no lo convertirá al caso apropiado. Podemos arreglar eso usando la función en minúscula dentro de esta manera:

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

Ahora esto convertirá todo lo que viene en Propercase.

Binod
fuente
17
public static string PropCase(string strText)
{
    return new CultureInfo("en").TextInfo.ToTitleCase(strText.ToLower());
}
Rajesh
fuente
1
Me gusta que haya agregado ToLower antes de ToTitleCase, cubre la situación en la que el texto de entrada es todo en mayúsculas.
joelc
7

Si alguien está interesado en la solución para Compact Framework:

return String.Join(" ", thestring.Split(' ').Select(i => i.Substring(0, 1).ToUpper() + i.Substring(1).ToLower()).ToArray());
Mibou
fuente
Con la interpolación de cadena: return string.Join ("", text.Split ('') .Seleccione (i => $ "{i.Substring (0, 1) .ToUpper ()} {i.Substring (1). ToLower ()} ") .ToArray ());
Ted
6

Aquí está la solución para ese problema ...

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

Use ToLower()primero, que CultureInfo.CurrentCulture.TextInfo.ToTitleCaseen el resultado para obtener la salida correcta.

    //---------------------------------------------------------------
    // 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
fuente
3

Necesitaba una forma de lidiar con todas las palabras mayúsculas, y me gustó la solución de Ricky AH, pero di un paso más para implementarla como un método de extensión. Esto evita el paso de tener que crear su conjunto de caracteres y luego llamar a ToArray explícitamente cada vez, por lo que puede llamarlo en la cadena, así:

uso:

string newString = oldString.ToProper();

código:

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
fuente
1
Acabo de agregar una condición OR más si (c == '' || c == '\' ') ... a veces los nombres contienen apóstrofes (').
JSK
2

Es mejor entender probando su propio código ...

Lee mas

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

1) Convertir una cadena a mayúsculas

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

2) Convertir una cadena a minúsculas

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

3) Convertir una cadena a TitleCase

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

Aquí hay una implementación, personaje por personaje. Debería funcionar 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);
}
Jeson Martajaya
fuente
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
fuente
1

Puede cambiar directamente el texto o la cadena a la correcta utilizando este método simple, después de verificar valores de cadena nulos o vacíos para eliminar errores:

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

Prueba esto:

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


Llame a este método en el evento TextChanged de TextBox.

Krishna
fuente
0

Utilicé las referencias anteriores y la solución completa es: -

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

// Necesitamos un resultado como "Infoa2z significa toda la información"
// Necesitamos convertir la cadena en minúsculas también, de lo contrario no funciona correctamente.

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

Esto es lo que uso y funciona para la mayoría de los casos a menos que el usuario decida anularlo presionando shift o mayúsculas. Al igual que en los teclados 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
Dasith Wijes
fuente
0

Para aquellos que buscan hacerlo automáticamente al presionar una tecla, lo hice con el siguiente código en vb.net en un control de cuadro de texto personalizado, obviamente también puede hacerlo con un cuadro de texto normal, pero me gusta la posibilidad de agregar código recurrente para controles específicos a través de controles personalizados, se adapta al concepto de 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
Andre Gotlieb
fuente
0

Funciona bien incluso con el caso de camello: '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
fuente
0

Como un método de extensión:

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

Resultado:

Kebab Is Deliciou's ;d C...

Español ricky
fuente
0

Alternativa con referencia a Microsoft.VisualBasic(también maneja cadenas en mayúscula):

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

Sin usar 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())));

Recorre cada letra en cada palabra, convirtiéndola en mayúsculas si es la primera letra, de lo contrario, se convierte en minúsculas.

facepalm42
fuente
-1

Sé que esta es una vieja pregunta, pero estaba buscando lo mismo para C y lo descubrí, así que pensé que lo publicaría si alguien más está buscando una manera 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
fuente