Convertendo seqüência de caracteres em maiúsculas e minúsculas

300

Eu tenho uma string que contém palavras em uma mistura de caracteres maiúsculos e minúsculos.

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

Preciso converter o primeiro caractere de cada palavra (separada por espaços) em maiúsculas. Então, eu quero o resultado como:string myData ="A Simple String";

Existe alguma maneira fácil de fazer isso? Não quero dividir a string e fazer a conversão (esse será meu último recurso). Além disso, é garantido que as strings estão em inglês.

Naveen
fonte
1
http://support.microsoft.com/kb/312890 - Como converter seqüências para inferior, superior ou título de caso (adequada) usando o Visual C #
ttarchala

Respostas:

538

MSDN: TextInfo.ToTitleCase

Certifique-se 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
fonte
37
Verdade. Além disso, se uma palavra estiver em maiúscula, ela não funcionará. por exemplo - "um agente do FBI matou meu CÃO" -> "Um agente do FBI matou meu CÃO". E ele não lida com "McDonalds", e assim por diante.
Kobi
5
@Kirschstein esta função faz conver estas palavras a caso de título, mesmo que eles não devem ser em Inglês. Consulte a documentação: Actual result: "War And Peace".
Kobi
5
@simbolo - eu realmente mencionei isso em um comentário ... Você pode usar algo como text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());, mas está longe de ser perfeito. Por exemplo, ele ainda não lida com aspas ou parênteses - "(one two three)"-> "(one Two Three)". Você pode fazer uma nova pergunta depois de descobrir exatamente o que deseja fazer com esses casos.
Kobi
17
Por alguma razão, quando eu tenho "DR", ele não se torna "Dr", a menos que eu chame .ToLower () antes de chamar ToTitleCase () ... Então isso é algo a ser observado ...
Tod Thomson
16
A .ToLower () para a cadeia de entrada é necessária se o texto de entrada é em letras maiúsculas
Puneet Ghanshani
137

Tente o seguinte:

string myText = "a Simple string";

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

Como já foi apontado, o uso de TextInfo.ToTitleCase pode não fornecer os resultados exatos que você deseja. Se você precisar de mais controle sobre a saída, poderá fazer algo assim:

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 então use-o assim:

var asTitleCase = new string( CharsToTitleCase(myText).ToArray() );
Winston Smith
fonte
1
Tentei várias variações do objeto TextInfo - sem erros, mas a string original (maiúscula) nunca foi atualizada. Conectou este método e sou muito grato.
justSteve
6
@justSteve, do MSDN ( msdn.microsoft.com/en-us/library/… ): "No entanto, atualmente, este método não fornece maiúsculas e minúsculas para converter uma palavra totalmente maiúscula, como um acrônimo" - você provavelmente apenas ToLower () pela primeira vez (Eu sei que este é antiga, mas apenas no caso de alguém tropeça outra pessoa sobre ele e se pergunta por!)
nizmow
Disponível apenas para .NET Framework 4.7.2 <= seu quadro funciona <= .NET Core 2.0 #
Paul Gorbas 10/10
70

Mais uma variação. Com base em várias dicas aqui, reduzi-o a este método de extensão, que funciona muito bem para meus propósitos:

public static string ToTitleCase(this string s) =>
    CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s.ToLower());
Todd Menier
fonte
8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); seria um ajuste melhor na verdade!
Puneet Ghanshani
Disponível apenas para o .NET Framework 4.7.2 <= seu quadro funciona <= .NET Core 2.0 #
Paul Gorbas 10/10
Como estamos usando InvariantCulture para TitleCasing, s.ToLowerInvariant () deve ser usado em vez de s.ToLower ().
Vinigas 28/08/19
27

Pessoalmente, tentei o TextInfo.ToTitleCasemétodo, mas não entendo por que ele não funciona quando todos os caracteres são maiúsculos.

Embora eu goste da função util fornecida por Winston Smith , deixe-me fornecer a função que estou usando atualmente:

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

Jogando com algumas seqüências de testes :

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 saída :

|Converting String To Title Case In C#|
|C|
||
|   |
||
Luis Quijada
fonte
1
@harsh: solução "feia", eu diria ... não faz sentido para mim que você primeiro converta toda a string em minúscula.
Luis Quijada
4
É intencional, porque, se você pedir, digamos, "UNICEF e caridade" para ter título, não deseja que seja alterado para Unicef.
Casey
4
Então, em vez de chamar ToLower()a string inteira, você prefere fazer tudo isso sozinho e chamar a mesma função em cada caractere individual? Não é apenas uma solução feia, está dando benefício zero e levaria até mais tempo do que a função interna.
krillgar
3
rest = words[i].Substring(1).ToLower();
precisa saber é o seguinte
1
@ruffin No. Substring com um único parâmetro int começa no índice fornecido e retorna tudo para o fim da cadeia.
krillgar
21

Recentemente eu encontrei uma solução melhor.

Se o seu texto contiver todas as letras em maiúsculas, o TextInfo não o converterá em maiúsculas e minúsculas. Podemos corrigir isso usando a função minúscula dentro desta forma:

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

Agora isso converterá tudo o que entra no Propercase.

Binod
fonte
17
public static string PropCase(string strText)
{
    return new CultureInfo("en").TextInfo.ToTitleCase(strText.ToLower());
}
Rajesh
fonte
1
Eu gosto que você adicionou o ToLower antes do ToTitleCase, cobre a situação em que o texto de entrada está em maiúsculas.
Joelc
7

Se alguém estiver interessado na solução para o Compact Framework:

return String.Join(" ", thestring.Split(' ').Select(i => i.Substring(0, 1).ToUpper() + i.Substring(1).ToLower()).ToArray());
Mibou
fonte
Com a interpolação de string: retorne string.Join ("", text.Split (''). Selecione (i => $ "{i.Substring (0, 1) .ToUpper ()} {i.Substring (1). ToLower ()} ") .ToArray ());
Ted
6

Aqui está a solução para esse problema ...

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

Use ToLower()primeiro, que CultureInfo.CurrentCulture.TextInfo.ToTitleCaseno resultado, para obter a saída correta.

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

Eu precisava de uma maneira de lidar com todas as palavras em maiúsculas e gostei da solução de Ricky AH, mas dei um passo adiante para implementá-la como um método de extensão. Isso evita a etapa de ter que criar sua matriz de caracteres e, em seguida, chamar o ToArray explicitamente todas as vezes - para que você possa chamá-lo na string, assim:

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
fonte
1
Acabei de adicionar mais uma condição OR se (c == '' || c == '\' ') ... às vezes os nomes contêm apóstrofes (').
JSK 27/11
2

É melhor entender tentando seu próprio código ...

Consulte Mais informação

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

1) Converter uma seqüência de caracteres em maiúsculas

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

2) Converter uma seqüência de caracteres em minúsculas

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

3) Converta uma String em TitleCase

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

Aqui está uma implementação, caractere por caractere. Deve funcionar com "(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
fonte
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
fonte
1

Você pode alterar diretamente o texto ou a string para a correta usando esse método simples, após verificar valores de string nulos ou vazios para eliminar erros:

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

Tente o seguinte:

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


Chame esse método no evento TextChanged do TextBox.

Krishna
fonte
0

Eu usei as referências acima e a solução completa é: -

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

// Precisa de um resultado como "Infoa2z significa todas as informações"
// Também precisamos converter a string em minúsculas, caso contrário, ela não está funcionando corretamente.

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

É isso que eu uso e funciona na maioria dos casos, a menos que o usuário decida substituí-lo pressionando shift ou caps lock. Como nos 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
fonte
0

Para aqueles que procuram fazê-lo automaticamente com o pressionamento de tecla, eu o fiz com o seguinte código no vb.net em um controle de caixa de texto personalizado - obviamente você também pode fazê-lo com uma caixa de texto normal - mas eu gosto da possibilidade de adicionar código recorrente para controles específicos via controles personalizados, ele se adapta ao conceito 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
fonte
0

Funciona bem, mesmo com estojo de camelo: '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
fonte
0

Como método de extensão:

/// <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...

Ricky Spanish
fonte
0

Alternativa com referência a Microsoft.VisualBasic(também manipula cadeias de caracteres maiúsculas):

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

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

Ele percorre todas as letras de cada palavra, convertendo-as em maiúsculas, se for a primeira letra, caso contrário, convertendo-as em minúsculas.

facepalm42
fonte
-1

Eu sei que essa é uma pergunta antiga, mas eu estava procurando a mesma coisa por C e descobri que seria possível publicá-la se alguém procurar por uma maneira em 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
fonte