Ubah semua huruf pertama menjadi huruf besar, sisanya lebih rendah untuk setiap kata

110

Saya memiliki serangkaian teks (sekitar 5-6 kata kebanyakan) yang perlu saya ubah.

Saat ini teksnya terlihat seperti:

THIS IS MY TEXT RIGHT NOW

Saya ingin mengubahnya menjadi:

This Is My Text Right Now

Saya dapat mengulang melalui koleksi string saya, tetapi tidak yakin bagaimana cara melakukan modifikasi teks ini.

mrblah
sumber

Jawaban:

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

s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
jspcal.dll
sumber
31
Haha benarkah? Di situlah tempatnya? Saya suka. NET tetapi beberapa desainer API benar-benar brengsek.
George Mauer
7
Perhatikan bahwa meskipun metode ini akan melakukan apa yang diminta oleh penanya, ini adalah algoritme naif yang hanya menggunakan huruf besar pada setiap kata, tanpa memperhatikan jenis kata apa. Ini sebenarnya bukan "kapitalisasi judul" karena aturan kapitalisasi judul berbeda dalam bahasa yang berbeda. Itu bahkan tidak benar untuk bahasa Inggris. Misalnya, judul "tentang seorang anak laki-laki" dalam bahasa Inggris harus "Tentang Anak Laki-Laki", tetapi metode ini akan menghasilkan "Tentang Anak Laki-Laki". Jika Anda menginginkan kasus judul yang benar , Anda harus menulis metode Anda sendiri.
Ryan Lundy
18
Saya tidak akan menyebut mereka brengsek. Masalah dengan "ToTitleCase" adalah bahwa hal itu bergantung pada budaya, oleh karena itu ia harus berada dalam namespace System.Globalization. Menelusuri CurrentThread baru saja dilakukan untuk mendapatkan Budaya Thread saat ini (Sadarilah bahwa ini dapat menyebabkan perilaku yang berbeda jika pengguna memiliki Lokal yang berbeda!). Anda juga bisa melakukan "CultureInfo.InvariantCulture.TextInfo.ToTitleCase ()", yang mungkin lebih baik karena InvariantCulture berperilaku sama di semua budaya. Karena minat, George: Di mana Anda akan meletakkan fungsi String Spesifik-Budaya?
Michael Stum
3
Perhatikan juga komentar tentang SEMUA string UPPERCASE
Michael Stum
2
metode toLower () harus ToLower (), huruf pertama dari metode dimulai dengan Huruf Besar
Alex
84

Saya mungkin lebih suka memanggil ToTitleCase dari CultureInfo ( System.Globalization ) daripada Thread.CurrentThread ( System.Threading )

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

tetapi harus sama dengan solusi jspcal

EDIT

Sebenarnya solusi tersebut tidak sama : 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

Referensi:

Filippo Vitale
sumber
16

Ada beberapa cara untuk mengubah karakter pertama dari string menjadi huruf besar.

Cara pertama adalah membuat metode yang hanya menutup karakter pertama dan menambahkan sisa string menggunakan substring:

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

Cara kedua (yang sedikit lebih cepat) adalah membagi string menjadi array karakter dan kemudian membangun kembali string tersebut:

public string UppercaseFirst(string s)
    {
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }
Jamie Dixon
sumber
1
Solusi ini tidak menjawab pertanyaan dengan tepat. Judul pertanyaannya adalah "Ubah semua huruf pertama menjadi huruf besar, huruf kecil untuk setiap kata". Namun, solusi ini hanya menggunakan huruf besar pertama dari seluruh string. Oleh karena itu, solusi ini akan mengubah "hello world" menjadi "Hello world", bukan "Hello World".
brsfan
9

Belum teruji tetapi sesuatu seperti ini seharusnya berfungsi:

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

Pada dasarnya ini mengatakan "membentuk sebelumnya pencocokan ekspresi reguler pada semua kemunculan karakter alfanumerik yang mengikuti karakter alfanumerik lain dan kemudian menggantinya dengan versi huruf kecil itu sendiri"

George Mauer
sumber
Yang ini juga membuat semua kata huruf besar dimulai dengan huruf besar dan dilanjutkan dengan huruf kecil. Persis apa yang saya cari.
M. Azyoksul
9

Jika Anda menggunakan di halaman web, Anda juga dapat menggunakan CSS:

style="text-transform:capitalize;"

M.Eren Çelik
sumber
2
Mengapa CSS? Ketika pertanyaan menanyakan c # asp.net regex
Jay
1
Tag tersebut ASP.NETmenunjukkan OP sedang melakukannya di WEB. Tentu ini bukan jawaban dari pertanyaan karena OP membutuhkan solusi yang masuk C#tetapi menyelesaikan masalah dan dapat menjadi solusi alternatif. +1
Muhammad Saqib
6

Saat membuat tabel besar, kecepatan menjadi perhatian, jadi fungsi kedua Jamie Dixon adalah yang terbaik, tetapi tidak sepenuhnya berfungsi sebagaimana mestinya ...

Itu gagal untuk mengambil semua huruf menjadi huruf kecil, dan itu hanya mengkapitalisasi huruf pertama dari string, bukan huruf pertama dari setiap kata dalam string ... opsi di bawah ini memperbaiki kedua masalah:

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

Meskipun pada titik ini, apakah ini masih pilihan tercepat masih belum pasti, Regexsolusi yang diberikan oleh George Mauer mungkin lebih cepat ... seseorang yang cukup peduli harus mengujinya.

Serj Sagan
sumber
2
itu berhasil, tetapi saya mengubah "a.Count ()" ini menjadi a.Length
Christian
2

Saya tidak tahu apakah solusi di bawah ini lebih atau kurang efisien daripada jawaban jspcal, tapi saya cukup yakin itu membutuhkan lebih sedikit pembuatan objek daripada Jamie dan 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();
singkat
sumber
1
Jika kita khawatir dengan pembuatan objek, mengapa tidak melakukannya di tempat dengan pengindeksan for loop melalui s daripada menggunakan StringBuilder?
jball
0

Selain jawaban pertama, ingatlah untuk mengubah indeks string selectionstart ke akhir kata atau Anda akan mendapatkan urutan huruf terbalik dalam string tersebut.

s.SelectionStart=s.Length;
zia khan
sumber
0

Coba teknik ini; Ini mengembalikan hasil yang diinginkan

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

Dan jangan lupa gunakan System.Globalization.

Beyondo
sumber
0

Salah satu solusi yang mungkin Anda minati. Melintasi array karakter dari kanan ke kiri dan sebaliknya dalam satu loop.

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);
    }
RShp
sumber
0

jawaban jspcal sebagai ekstensi string.

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());
    }
}
Joel Wiklund
sumber