Перетворення рядка в регістр заголовка


300

У мене є рядок, який містить слова в суміші великих і малих символів.

Наприклад: string myData = "a Simple string";

Мені потрібно перетворити перший символ кожного слова (розділеного пробілами) у верхній регістр. Тому я хочу результат:string myData ="A Simple String";

Чи є якийсь простий спосіб зробити це? Я не хочу розділяти рядок і робити перетворення (це буде моїм останнім засобом). Також гарантується, що рядки англійською мовою.


1
http://support.microsoft.com/kb/312890 - Як конвертувати рядки в нижній, верхній чи титульний (правильний) регістр, використовуючи Visual C #
ttarchala

Відповіді:


538

MSDN: TextInfo.ToTitleCase

Переконайтеся, що ви включаєте: 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
Правда. Крім того, якщо слово є великим регістром, воно не працює. наприклад - "агент ФБР застрелив мою собаку" -> "Агент ФБР застрелив мою собаку". І він не обробляє "Макдональдс" тощо.
Кобі

5
@Kirschstein ця функція робить Conver ці слова в заголовку справи, незважаючи на те, що вони не повинні бути англійською мовою. Зверніться до документації: Actual result: "War And Peace".
Кобі

5
@simbolo - я все-таки згадував це у коментарі ... Можна використовувати щось на кшталт text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());, але це далеко не ідеально. Наприклад, він все ще не обробляє лапки або дужки - "(one two three)"-> "(one Two Three)". Можливо, ви захочете задати нове запитання після того, як з’ясуєте, що саме ви хочете робити в цих випадках.
Кобі

17
З якої - то причини , коли у мене є «DR» він не стане «Dr» , якщо я не називаю .ToLower () перед викликом першого ToTitleCase () ... Так що це що - то , щоб стежити за ...
Тод Томсон

16
.ToLower () для введення рядка потрібен, якщо текст введення у верхньому регістрі
Puneet Ghanshani

137

Спробуйте це:

string myText = "a Simple string";

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

Як уже було зазначено, використання TextInfo.ToTitleCase може не дати точних результатів, які ви хочете. Якщо вам потрібен більший контроль над висновком, ви можете зробити щось подібне:

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

А потім використовуйте так:

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

1
Я спробував кілька варіантів об’єкта TextInfo - помилок не було, але початковий рядок (верхній регістр) ніколи не оновлювався. Підключено цей метод і я дуже вдячний.
justSteve

6
@justSteve, з MSDN ( msdn.microsoft.com/en-us/library/… ): "Однак, цей метод наразі не забезпечує належного обліку для перетворення слова, яке є повністю великим літером , наприклад, абревіатура" - ви, ймовірно, повинні просто ToLower () він спочатку (я знаю, що це старе, але на всякий випадок, якщо хтось інший натикається на нього і цікавиться чому!)
nizmow

Доступно лише для .NET Framework 4.7.2 <= робота над вашими кадрами <= .NET Core 2.0
Пол Горбас

70

Ще одна варіація. На основі декількох порад тут я звів її до цього методу розширення, який чудово підходить для моїх цілей:

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

8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); було б краще підходити насправді!
Пунеет Ганшані

Доступно лише для .NET Framework 4.7.2 <= робота над вашими кадрами <= .NET Core 2.0
Пол Горбас

Оскільки ми використовуємо InvariantCulture для TitleCasing, s.ToLowerInvariant () слід використовувати замість s.ToLower ().
Вінігас

27

Особисто я спробував TextInfo.ToTitleCaseметод, але я не розумію, чому він не працює, коли всі символи мають верхній облік.

Хоча мені подобається утиліта, яку надає Вінстон Сміт , дозвольте мені надати функцію, яку я зараз використовую:

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

Гра з деякими тестами :

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

Даючи вихід :

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

1
@harsh: "Потворне" рішення, я б сказав, немає сенсу для мене, що ви повинні спочатку перетворити всю нитку в малі регістри.
Луїс Кіяда

4
Це навмисно, тому що якщо ви попросите, скажімо, "ЮНІСЕФ та благодійність", щоб це було визначено назви, ви не хочете, щоб він був змінений на Unicef.
Кейсі

4
Отже, замість того, щоб зателефонувати ToLower()на весь рядок, ви б краще зробити все це самостійно і викликати ту саму функцію для кожного окремого символу? Мало того, що це некрасиве рішення, воно дає нульову користь і навіть забирає більше часу, ніж вбудована функція.
крильгар

3
rest = words[i].Substring(1).ToLower();
крильгар

1
@ruffin No. подстрока з одиночним починається параметр INT в даному індексі, і повертає всі до кінця рядка.
крильгар

21

Нещодавно я знайшов краще рішення.

Якщо ваш текст містить кожну літеру з великої літери, TextInfo не перетворить її у відповідний регістр. Ми можемо це виправити, використовуючи маленьку функцію всередині:

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

Тепер це перетворить усе, що потрапляє, у "власне".


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

1
Мені подобається, що ви додали ToLower до ToTitleCase, охоплює ситуацію, коли вхідний текст є усіма обмеженнями.
joelc

7

Якщо хтось зацікавлений у вирішенні Compact Framework:

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

З інтерполяцією рядків: return string.Join ("", text.Split ('') .Select (i => $ "{i.Substring (0, 1) .ToUpper ()} {i.Substring (1). ToLower ()} ") .ToArray ());
Тед

6

Ось рішення цієї проблеми ...

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

5

Скористайтеся ToLower()спочатку, ніж CultureInfo.CurrentCulture.TextInfo.ToTitleCaseза результатом, щоб отримати правильний результат.

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

Мені знадобився спосіб розібратися з усіма словами з великої літери, і мені сподобалося рішення Рікі АН, але я зробив крок далі, щоб реалізувати це як метод розширення. Це дозволяє уникнути необхідності створювати свій масив символів, а потім викликати ToArray на ньому явно кожен раз - так що ви можете просто зателефонувати на рядок, наприклад:

використання:

string newString = oldString.ToProper();

код:

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
Просто додано ще одну умову АБО, якщо (c == '' || c == '\' ') ... іноді імена містять апострофи (').
JSK

2

Його краще зрозуміти, спробувавши власний код ...

Детальніше

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

1) Перетворіть рядок у верхній регістр

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

2) Перетворити рядок у малі регістри

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

3) Перетворити рядок у TitleCase

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

1

Ось реалізація, характер за характером. Слід працювати з "(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

Ви можете безпосередньо змінити текст або рядок на належний за допомогою цього простого методу після перевірки наявності нульових чи порожніх рядкових значень, щоб усунути помилки:

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

Спробуйте це:

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


Викличте цей метод у події TextChanged TextBox.


0

Я використовував вищезазначені посилання і повне рішення:

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

// Потрібен такий результат, як "Infoa2z означає всю інформацію"
// Нам також потрібно перетворити рядок в малі регіони , інакше вона не працює належним чином.

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

Це те, що я використовую, і це працює в більшості випадків, якщо користувач не вирішить його замінити натисканням клавіші shift або caps lock. Як і на клавіатурах Android та 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

Для тих, хто прагне зробити це автоматично під час натискання клавіші, я зробив це з наступним кодом в vb.net на користувальницькому текстовому контролі - ви, очевидно, також можете це зробити із звичайним текстовим полем, - але мені подобається можливість додавати повторюваний код для конкретних елементів керування За допомогою користувацьких елементів управління воно відповідає концепції 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

Добре працює навіть у випадку з верблюдом: "someText у своїй сторінці"

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

Як метод розширення:

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

Використання:

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

Результат:

Kebab Is Deliciou's ;d C...



0

Без використання 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())));

Він проходить через кожну букву в кожному слові, перетворюючи її в великі регістри, якщо це перша буква, інакше перетворюючи її в малі регістри.


-1

Я знаю це давнє запитання, але я шукав те ж саме для C, і я зрозумів це, тому зрозумів, що опублікую його, якщо хтось інший шукає шлях у 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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.