Konwertowanie ciągu znaków na wielkość liter


300

Mam ciąg znaków, który zawiera słowa złożone z wielkich i małych liter.

Na przykład: string myData = "a Simple string";

Muszę przekonwertować pierwszy znak każdego słowa (oddzielony spacjami) na wielkie litery. Więc chcę wynik jako:string myData ="A Simple String";

Czy jest jakiś prosty sposób to zrobić? Nie chcę dzielić łańcucha i wykonywać konwersji (to będzie moja ostatnia deska ratunku). Ponadto zagwarantowane jest, że ciągi są w języku angielskim.


1
http://support.microsoft.com/kb/312890 - Jak przekonwertować ciągi do litery, małe litery lub tytuł (właściwa) za pomocą programu Visual C #
ttarchala

Odpowiedzi:


538

MSDN: TextInfo.ToTitleCase

Upewnij się, że podałeś: 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
Prawdziwe. Ponadto, jeśli słowo jest pisane wielkimi literami, nie działa. np. „agent FBI zastrzelił mojego psa” -> „agent FBI zastrzelił mojego psa”. I nie obsługuje „McDonalds” i tak dalej.
Kobi

5
@Kirschstein ta funkcja robi Conver te słowa do tytułowej przypadku, mimo że nie powinny być w języku angielskim. Zapoznaj się z dokumentacją: Actual result: "War And Peace".
Kobi

5
@ simbolo - I rzeczywiście wspomniałem o tym w komentarzu ... Możesz użyć czegoś takiego text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());, ale jest to dalekie od ideału. Na przykład nadal nie obsługuje cudzysłowów ani nawiasów - "(one two three)"-> "(one Two Three)". Możesz zadać nowe pytanie po tym, jak dokładnie określisz, co chcesz zrobić z tymi przypadkami.
Kobi

17
Z jakiegoś powodu, gdy mam „DR”, nie staje się „Dr”, chyba że najpierw wywołam .ToLower () przed wywołaniem ToTitleCase () ... Więc jest to coś, na co należy uważać ...
Tod Thomson

16
A .ToLower () do ciągu wejściowego jest wymagane, jeśli tekst wejściowy jest
pisany

137

Spróbuj tego:

string myText = "a Simple string";

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

Jak już wspomniano, użycie TextInfo.ToTitleCase może nie dać ci dokładnie takich rezultatów, jak chcesz. Jeśli potrzebujesz większej kontroli nad wyjściem, możesz zrobić coś takiego:

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

A następnie użyj go w następujący sposób:

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

1
Próbowałem kilku odmian obiektu TextInfo - żadnych błędów, ale oryginalny ciąg (wielkie litery) nigdy nie był aktualizowany. Podłączyłem tę metodę i jestem bardzo wdzięczny.
justSteve,

6
@justSteve, z MSDN ( msdn.microsoft.com/en-us/library/... ): „Jednak ta metoda nie zapewnia obecnie odpowiedniej obudowy do konwersji słowa, które jest całkowicie wielkie, np. akronim” - prawdopodobnie powinieneś tylko ToLower () to pierwszy (wiem, że to jest stare, ale na wypadek, gdyby ktoś inny potknął się o to i zastanawiał się dlaczego!)
nizmow

Dostępne tylko dla .NET Framework 4.7.2 <= praca ramki <= .NET Core 2.0
Paul Gorbas 10.10-18

70

Kolejna odmiana. Na podstawie kilku wskazówek tutaj ograniczyłem go do tej metody rozszerzenia, która działa świetnie dla moich celów:

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

8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); byłoby lepiej pasować!
Puneet Ghanshani

Dostępna tylko dla .NET Framework 4.7.2 <= praca rama <= Rdzeń .NET 2.0
Paweł Gorbas

Ponieważ używamy InvariantCulture do TitleCasing, zamiast s.ToLower () należy użyć s.ToLowerInvariant ().
Vinigas

27

Osobiście wypróbowałem tę TextInfo.ToTitleCasemetodę, ale nie rozumiem, dlaczego nie działa, gdy wszystkie znaki są wielkie.

Chociaż podoba mi się funkcja util zapewniana przez Winstona Smitha , pozwól mi podać funkcję, której aktualnie używam:

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

Gra z kilkoma ciągami testów :

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

Dając wynik :

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

1
@harsh: „brzydkie” rozwiązanie Powiedziałbym ... nie ma dla mnie sensu, że najpierw musisz przekonwertować cały ciąg na małe litery.
Luis Quijada,

4
Jest to celowe, ponieważ jeśli poprosisz, powiedzmy, „UNICEF i organizacja charytatywna” o tytuł, nie chcesz, aby zmieniła się na Unicef.
Casey

4
Więc zamiast wywoływać ToLower()cały ciąg, wolisz wykonać całą tę pracę samemu i wywołać tę samą funkcję dla każdego pojedynczego znaku? Jest to nie tylko brzydkie rozwiązanie, ale daje zerową korzyść, a nawet zajęłoby dłużej niż wbudowana funkcja.
krillgar

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

1
@ruffin nr podciągu za pomocą jednego parametru int startów w danym indeksie, i wraca wszystko do końca łańcucha.
krillgar

21

Ostatnio znalazłem lepsze rozwiązanie.

Jeśli twój tekst zawiera każdą literę dużymi literami, TextInfo nie przekonwertuje go na odpowiednią wielkość liter. Możemy to naprawić za pomocą funkcji małych liter wewnątrz:

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

Teraz to skonwertuje wszystko, co przychodzi do Propercase.


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

1
Podoba mi się, że dodałeś ToLower przed ToTitleCase, obejmuje sytuację, w której tekst wejściowy składa się z wielkich liter.
joelc,

7

Jeśli ktoś jest zainteresowany rozwiązaniem dla Compact Framework:

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

Z interpolacją ciągów: zwróć ciąg.Join ("", text.Split ('') .Wybierz (i => $ "{i.Substring (0, 1) .ToUpper ()} {i.Substring (1). ToLower ()} ") .ToArray ());
Ted

6

Oto rozwiązanie tego problemu ...

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

5

Użyj ToLower()najpierw, a nie CultureInfo.CurrentCulture.TextInfo.ToTitleCasewyniku, aby uzyskać poprawny wynik.

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

Potrzebowałem sposobu na radzenie sobie ze wszystkimi słowami wielkimi literami i podobało mi się rozwiązanie Ricky AH, ale zrobiłem krok dalej, aby wdrożyć go jako metodę rozszerzenia. Dzięki temu unika się konieczności tworzenia tablicy znaków, a następnie jawnego wywoływania na niej ToArray za każdym razem - dzięki czemu można po prostu wywołać ciąg znaków, tak jak poniżej:

stosowanie:

string newString = oldString.ToProper();

kod:

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
Właśnie dodałem jeszcze jeden warunek LUB, jeśli (c == '' || c == '\' ') ... czasami nazwy zawierają apostrofy (').
JSK

2

Lepiej to zrozumieć, wypróbowując własny kod ...

Czytaj więcej

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

1) Konwertuj ciąg na wielkie litery

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

2) Konwertuj ciąg na małe litery

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

3) Konwertuj ciąg na TitleCase

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

1

Oto implementacja, znak po znaku. Powinien działać z „(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

Za pomocą tej prostej metody możesz bezpośrednio zmienić tekst lub ciąg znaków na właściwy, po sprawdzeniu pustych lub pustych wartości ciągu w celu wyeliminowania błędów:

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

Spróbuj tego:

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


Wywołaj tę metodę w zdarzeniu TextChanged obiektu TextBox.


0

Użyłem powyższych referencji i kompletnym rozwiązaniem jest:

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

// Potrzebujesz wyniku takiego jak „Infoa2z oznacza wszystkie informacje”
// Musimy również przekonwertować ciąg znaków małymi literami, w przeciwnym razie nie będzie działał poprawnie.

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

To jest to, czego używam i działa w większości przypadków, chyba że użytkownik zdecyduje się to zmienić, naciskając Shift lub Caps Lock. Podobnie jak na klawiaturach z Androidem i 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

Dla tych, którzy chcą to zrobić automatycznie po naciśnięciu klawisza, zrobiłem to z następującym kodem w vb.net na niestandardowym polu tekstowym - możesz oczywiście zrobić to również za pomocą zwykłego pola tekstowego - ale lubię możliwość dodawania powtarzającego się kodu dla określonych elementów sterujących za pomocą niestandardowych elementów sterujących odpowiada koncepcji 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

Działa dobrze nawet w przypadku wielbłąda: „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

Jako metoda rozszerzenia:

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

Stosowanie:

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

Wynik:

Kebab Is Deliciou's ;d C...


0

Alternatywnie w odniesieniu do Microsoft.VisualBasic(obsługuje również ciągi wielkich liter):

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

0

Bez użycia 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())));

Pętla przechodzi przez każdą literę w każdym słowie, konwertując go na wielkie litery, jeśli jest to pierwsza litera, w przeciwnym razie konwertuje go na małe litery.


-1

Znam to stare pytanie, ale szukałem tego samego dla C i wymyśliłem to, więc pomyślałem, że opublikuję to, jeśli ktoś inny szuka sposobu w 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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.