Chuyển tất cả chữ cái đầu tiên thành chữ hoa, viết thường cho mỗi từ


110

Tôi có một chuỗi văn bản (chủ yếu là khoảng 5-6 từ) mà tôi cần chuyển đổi.

Hiện tại, văn bản trông giống như:

THIS IS MY TEXT RIGHT NOW

Tôi muốn chuyển đổi nó thành:

This Is My Text Right Now

Tôi có thể lặp lại bộ sưu tập các chuỗi của mình, nhưng không chắc về cách thực hiện sửa đổi văn bản này.

Câu trả lời:


251
string s = "THIS IS MY TEXT RIGHT NOW";

s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

31
Haha, thật á? Đó là nơi nó ở? Tôi yêu .NET nhưng một số nhà thiết kế API là những kẻ thực sự.
George Mauer

7
Lưu ý rằng mặc dù phương pháp này sẽ thực hiện những gì người hỏi đã yêu cầu, nhưng đó là một thuật toán ngây thơ chỉ viết hoa mỗi từ mà không cần quan tâm đến loại từ đó là gì. Nó không hẳn là "viết hoa tiêu đề" vì các quy tắc viết hoa tiêu đề khác nhau ở các ngôn ngữ khác nhau. Nó thậm chí không chính xác cho tiếng Anh. Ví dụ: tiêu đề "about a boy" phải là "About a Boy" bằng tiếng Anh, nhưng phương pháp này sẽ là "About A Boy". Nếu bạn muốn viết hoa tiêu đề đúng , bạn sẽ phải viết phương pháp của riêng mình.
Ryan Lundy

18
Tôi sẽ không gọi họ là đồ ngốc. Vấn đề với "ToTitleCase" là nó phụ thuộc vào văn hóa, do đó nó phải nằm trong không gian tên System.Globalization. Đi qua CurrentThread chỉ là xong để lấy Văn hóa hiện tại của Chủ đề (Lưu ý rằng điều này có thể gây ra hành vi khác nhau nếu người dùng có Ngôn ngữ khác!). Bạn cũng có thể thực hiện "CultureInfo.InvariantCulture.TextInfo.ToTitleCase ()", có thể tốt hơn vì InvariantCulture hoạt động giống nhau trên tất cả các nền văn hóa. Không quan tâm George: Bạn sẽ đặt hàm Chuỗi dành riêng cho Văn hóa ở đâu?
Michael Stum

3
Cũng lưu ý các nhận xét về TẤT CẢ các chuỗi UPPERCASE: msdn.microsoft.com/en-us/library/…
Michael Stum

2
phương thức toLower () phải là ToLower (), chữ cái đầu tiên của phương thức bắt đầu bằng chữ hoa
Alex

84

Tôi có lẽ thích gọi ToTitleCase từ CultureInfo ( System.Globalization ) hơn Thread.CurrentThread ( System.Threading )

string s = "THIS IS MY TEXT RIGHT NOW";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

nhưng nó phải giống như giải pháp jspcal

BIÊN TẬP

Thực ra những giải pháp đó không giống nhau : CurrentThread--calls -> CultureInfo!


System.Threading.Thread.CurrentThread.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Threading.Thread.get_CurrentThread
IL_000B:  callvirt    System.Threading.Thread.get_CurrentCulture
IL_0010:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0015:  ldloc.0     // s
IL_0016:  callvirt    System.String.ToLower
IL_001B:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_0020:  stloc.0     // s

System.Globalization.CultureInfo.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Globalization.CultureInfo.get_CurrentCulture
IL_000B:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0010:  ldloc.0     // s
IL_0011:  callvirt    System.String.ToLower
IL_0016:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_001B:  stloc.0     // s

Người giới thiệu:


16

Có một số cách để chuyển đổi ký tự đầu tiên của chuỗi thành chữ hoa.

Cách đầu tiên là tạo một phương thức chỉ cần viết hoa ký tự đầu tiên và nối phần còn lại của chuỗi bằng cách sử dụng một chuỗi con:

public string UppercaseFirst(string s)
    {
        return char.ToUpper(s[0]) + s.Substring(1);
    }

Cách thứ hai (nhanh hơn một chút) là chia chuỗi thành một mảng char và sau đó xây dựng lại chuỗi:

public string UppercaseFirst(string s)
    {
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

1
Giải pháp này không trả lời chính xác câu hỏi một cách đầy đủ. Tiêu đề của câu hỏi là "Chuyển tất cả chữ cái đầu tiên thành chữ hoa, phần còn lại viết thường cho mỗi từ". Tuy nhiên, giải pháp này chỉ viết hoa chữ cái đầu tiên của toàn bộ chuỗi. Do đó, giải pháp này sẽ chuyển đổi "hello world" thành "Hello world", thay vì "Hello World".
brsfan

9

Chưa được kiểm tra nhưng một cái gì đó như thế này sẽ hoạt động:

var phrase = "THIS IS MY TEXT RIGHT NOW";
var rx = new System.Text.RegularExpressions.Regex(@"(?<=\w)\w");
var newString = rx.Replace(phrase,new MatchEvaluator(m=>m.Value.ToLowerInvariant()));

Về cơ bản, nó nói "định dạng trước một trận đấu regex trên tất cả các lần xuất hiện của một ký tự chữ và số theo sau một ký tự chữ và số khác và sau đó thay thế nó bằng một phiên bản chữ thường của chính nó"


Điều này cũng làm cho tất cả các từ viết hoa bắt đầu bằng chữ hoa và tiếp tục bằng chữ thường. Chính xác những gì tôi đang tìm kiếm.
M. Azyoksul

9

Nếu bạn đang sử dụng trên một trang web, bạn cũng có thể sử dụng CSS:

style="text-transform:capitalize;"


2
Tại sao CSS? Khi câu hỏi được đặt ra cho c # asp.net regex
Jay

1
Thẻ ASP.NETcho thấy OP đang làm điều đó trên WEB. Tất nhiên đây không phải là câu trả lời của câu hỏi vì OP yêu cầu giải pháp trong C#nhưng nó giải quyết được vấn đề và có thể là một giải pháp thay thế. +1
Muhammad Saqib

6

Khi xây dựng các bảng lớn, tốc độ là một mối quan tâm vì vậy chức năng thứ hai của Jamie Dixon là tốt nhất, nhưng nó không hoàn toàn hoạt động như ...

Nó không thể chuyển tất cả các chữ cái thành chữ thường và nó chỉ viết hoa chữ cái đầu tiên của chuỗi, không phải chữ cái đầu tiên của mỗi từ trong chuỗi ... tùy chọn dưới đây khắc phục cả hai vấn đề:

    public string UppercaseFirstEach(string s)
    {
        char[] a = s.ToLower().ToCharArray();

        for (int i = 0; i < a.Count(); i++ )
        {
            a[i] = i == 0 || a[i-1] == ' ' ? char.ToUpper(a[i]) : a[i];

        }

        return new string(a);
    }

Mặc dù tại thời điểm này, liệu đây có phải là lựa chọn nhanh nhất hay không là điều không chắc chắn, nhưng Regexgiải pháp được cung cấp bởi George Mauer có thể nhanh hơn ... một người đủ quan tâm nên thử nghiệm nó.


2
nó hoạt động, nhưng tôi đã thay đổi "a.Count ()" này thành a.Length
Christian

2

Tôi không biết liệu giải pháp bên dưới có hiệu quả hơn hay kém hơn câu trả lời của jspcal hay không, nhưng tôi khá chắc chắn rằng nó yêu cầu ít tạo đối tượng hơn so với của Jamie và George.

string s = "THIS IS MY TEXT RIGHT NOW";
StringBuilder sb = new StringBuilder(s.Length);
bool capitalize = true;
foreach (char c in s) {
    sb.Append(capitalize ? Char.ToUpper(c) : Char.ToLower(c));
    capitalize = !Char.IsLetter(c);
}
return sb.ToString();

1
Nếu chúng ta quan tâm đến việc tạo đối tượng, tại sao không thực hiện nó tại chỗ với lập chỉ mục vòng lặp for thay vì sử dụng StringBuilder?
jball

0

Ngoài câu trả lời đầu tiên, hãy nhớ thay đổi chỉ mục phần chọn chuỗi thành cuối từ, nếu không bạn sẽ nhận được thứ tự ngược lại của các chữ cái trong chuỗi.

s.SelectionStart=s.Length;

0

Hãy thử kỹ thuật này; Nó trả về kết quả mong muốn

CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());

Và đừng quên sử dụng System.Globalization.


0

Một trong những giải pháp khả thi mà bạn có thể quan tâm. Chuyển một mảng ký tự từ phải sang trái và ngược lại trong một vòng lặp.

public static string WordsToCapitalLetter(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException("value");
        }

        int inputValueCharLength = value.Length;
        var valueAsCharArray = value.ToCharArray();

        int min = 0;
        int max = inputValueCharLength - 1;

        while (max > min)
        {
            char left = value[min];
            char previousLeft = (min == 0) ? left : value[min - 1];

            char right = value[max];
            char nextRight = (max == inputValueCharLength - 1) ? right : value[max - 1];

            if (char.IsLetter(left) && !char.IsUpper(left) && char.IsWhiteSpace(previousLeft))
            {
                valueAsCharArray[min] = char.ToUpper(left);
            }

            if (char.IsLetter(right) && !char.IsUpper(right) && char.IsWhiteSpace(nextRight))
            {
                valueAsCharArray[max] = char.ToUpper(right);
            }

            min++;
            max--;
        }

        return new string(valueAsCharArray);
    }

0

câu trả lời của jspcal dưới dạng phần mở rộng chuỗi.

Program.cs

class Program
{
    static void Main(string[] args)
    {
        var myText = "MYTEXT";
        Console.WriteLine(myText.ToTitleCase()); //Mytext
    }
}

StringExtensions.cs

using System;
public static class StringExtensions
{

    public static string ToTitleCase(this string str)
    {
        if (str == null)
            return null;

        return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.