การแปลงสตริงเป็นกรณีตัวพิมพ์ใหญ่


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
จริง นอกจากนี้หากคำเป็นตัวพิมพ์ใหญ่ทั้งหมดจะไม่ทำงาน เช่น - "ตัวแทน FBI ยิงสุนัขของฉัน" -> "ตัวแทน FBI ยิงสุนัขของฉัน" และมันก็ไม่ได้จัดการกับ "McDonalds" และอื่น ๆ
Kobi

5
@Kirschstein ฟังก์ชั่นนี้ไม่ Conver คำเหล่านี้กับกรณีชื่อถึงแม้ว่าพวกเขาไม่ควรจะเป็นภาษาอังกฤษ Actual result: "War And Peace"โปรดดูเอกสาร:
Kobi

5
@simbolo - ฉันไม่ได้พูดถึงมันในความคิดเห็น ... คุณสามารถใช้สิ่งที่ชอบtext = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());แต่มันก็ยังห่างไกลจากความสมบูรณ์แบบ ยกตัวอย่างเช่นมันยังไม่ได้จัดการกับคำพูดหรือวงเล็บ - ->"(one two three)" "(one Two Three)"คุณอาจต้องการถามคำถามใหม่หลังจากที่คุณทราบว่าคุณต้องการทำอะไรกับกรณีเหล่านี้
Kobi

17
ด้วยเหตุผลบางอย่างเมื่อฉันมี "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
Paul Gorbas

70

อีกรูปแบบหนึ่ง จากเคล็ดลับหลายประการที่นี่ฉันได้ลดวิธีการส่วนขยายนี้ซึ่งใช้งานได้ดีสำหรับวัตถุประสงค์ของฉัน:

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

8
CultureInfo.InvariantCulture.TextInfo.ToTitleCase (s.ToLower ()); จะเป็นแบบที่ดีขึ้นจริง!
Puneet Ghanshani

ใช้ได้เฉพาะกับ. NET Framework 4.7.2 <= กรอบการทำงานของคุณ <=. NET Core 2.0
Paul Gorbas

เนื่องจากเราใช้ InvariantCulture สำหรับ TitleCasing ควรใช้ s.ToLowerInvariant () แทน s.ToLower ()
Vinigas

27

โดยส่วนตัวฉันลองใช้TextInfo.ToTitleCaseวิธีนี้ แต่ฉันไม่เข้าใจว่าทำไมมันไม่ทำงานเมื่อตัวอักษรทั้งหมดเป็นตัวพิมพ์ใหญ่

แม้ว่าฉันจะชอบฟังก์ชั่น util ที่จัดทำโดยWinston Smithฉันขอมอบฟังก์ชั่นที่ฉันกำลังใช้อยู่:

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: การแก้ปัญหา "น่าเกลียด" ฉันจะบอกว่า ... มันไม่มีเหตุผลสำหรับฉันที่คุณต้องแปลงสตริงทั้งหมดเป็นตัวพิมพ์เล็ก
Luis Quijada

4
มันเป็นความตั้งใจเพราะถ้าคุณขอพูดว่า "ยูนิเซฟและการกุศล" เป็นชื่อที่ใส่ซองคุณไม่ต้องการให้มันเปลี่ยนเป็นยูนิเซฟ
Casey

4
ดังนั้นแทนที่จะโทรToLower()ไปที่สายอักขระทั้งหมดคุณอยากทำงานทั้งหมดด้วยตัวเองและเรียกใช้ฟังก์ชันเดียวกันกับอักขระแต่ละตัว? ไม่เพียง แต่เป็นโซลูชั่นที่น่าเกลียด แต่ยังให้ประโยชน์เป็นศูนย์และอาจใช้เวลานานกว่าฟังก์ชั่นในตัว
krillgar

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

1
@ruffin เลขSubstringเดียวกับพารามิเตอร์ int เริ่มต้นที่ดัชนีที่กำหนดและผลตอบแทนทุกอย่างถึงจุดสิ้นสุดของสตริง
krillgar

21

เมื่อเร็ว ๆ นี้ฉันพบวิธีแก้ปัญหาที่ดีกว่า

หากข้อความของคุณมีตัวอักษรทุกตัวเป็นตัวพิมพ์ใหญ่TextInfoจะไม่แปลงเป็นตัวพิมพ์ใหญ่ เราสามารถแก้ไขได้โดยใช้ฟังก์ชันตัวพิมพ์เล็กด้านใน:

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

ตอนนี้จะแปลงทุกอย่างที่เข้ามาใน Propercase


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

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

ฉันต้องการวิธีจัดการกับคำที่พิมพ์ออกทั้งหมดและฉันชอบโซลูชันของ Ricky AH แต่ฉันใช้ขั้นตอนต่อไปเพื่อนำไปใช้เป็นวิธีการขยาย วิธีนี้จะช่วยหลีกเลี่ยงขั้นตอนในการสร้างอาร์เรย์ของตัวอักษรจากนั้นเรียก 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 == '\' ') ... บางครั้งชื่อมี apostrophes (')
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

นี่คือการใช้งานตัวละครตัวละคร ควรทำงานกับ "(หนึ่งสองสาม)"

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 เหตุการณ์ของกล่องข้อความ


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

สำหรับคนที่กำลังมองหาที่จะทำมันโดยอัตโนมัติใน keypress ฉันทำมันด้วยรหัสต่อไปนี้ใน vb.net บน textboxcontrol ที่กำหนดเอง - คุณสามารถทำมันกับ textbox ธรรมดาได้อย่างชัดเจน - แต่ฉันชอบความเป็นไปได้ที่จะเพิ่ม code ซ้ำ ๆ ผ่านการควบคุมที่กำหนดเองมันเหมาะกับแนวคิดของ 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 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

เป็นวิธีการขยาย:

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

ทางเลือกที่มีการอ้างอิงถึงMicrosoft.VisualBasic(จัดการกับสตริงตัวพิมพ์ใหญ่ด้วย):

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

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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.