Tüm ilk harfleri büyük harfe dönüştür, her kelime için daha alçak


110

Dönüştürmem gereken (çoğunlukla yaklaşık 5-6 kelime) bir metin dizim var.

Şu anda metin şöyle görünüyor:

THIS IS MY TEXT RIGHT NOW

Bunu şuna dönüştürmek istiyorum:

This Is My Text Right Now

Dizge koleksiyonumda dolaşabilirim, ancak bu metin değişikliğini nasıl gerçekleştireceğimden emin değilim.

Yanıtlar:


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

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

31
Haha gerçekten mi? O nerede? .NET'i seviyorum ama bazı API tasarımcıları gerçekten gerizekalı.
George Mauer

7
Bu yöntem, soruyu soran kişinin sorduğu şeyi yapacak olsa da, ne tür bir kelime olduğuna bakılmaksızın her kelimeyi büyük harfle yazan saf bir algoritmadır. Başlık büyüklüğüne ilişkin kurallar farklı dillerde farklılık gösterdiğinden bu gerçekten "başlık durumu" değildir. İngilizce için bile doğru değil. Örneğin, "bir erkek hakkında" başlığı İngilizce'de "Bir Erkek Hakkında" olmalıdır, ancak bu yöntem "Bir Erkek Hakkında" değerini verecektir. İsterseniz gerçek başlık durumda, kendi yöntemini yazmak gerekecek.
Ryan Lundy

18
Onlara pislik demezdim. "ToTitleCase" ile ilgili olan şey, kültüre bağlı olmasıdır, dolayısıyla System.Globalization ad alanında olması gerekir. CurrentThread üzerinden geçmek sadece geçerli İş Parçacığının Kültürünü almak için yapılır (Kullanıcının farklı bir Yerel Ayarı varsa bunun farklı davranışlara neden olabileceğini unutmayın!). InvariantCulture tüm kültürlerde aynı şekilde davrandığı için "CultureInfo.InvariantCulture.TextInfo.ToTitleCase ()" de yapabilirsiniz. İlgi dışı George: Kültüre Özgü Dize işlevini nereye koyardınız?
Michael Stum

3
Ayrıca TÜM BÜYÜK HARF dizeleri hakkındaki yorumlara da dikkat edin: msdn.microsoft.com/en-us/library/…
Michael Stum

2
toLower () yöntemi ToLower () olmalıdır, yöntemin ilk harfi Büyük harfle başlamalıdır
Alex

84

Muhtemelen çağırmak için tercih ToTitleCase dan CultureınfoRegionInfo ( System.Globalization hariç) Thread.CurrentThread ( System.Threading )

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

ancak jspcal çözümüyle aynı olmalıdır

DÜZENLE

Aslında bu çözümler aynı değil : 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

Referanslar:


16

Bir dizenin ilk karakterini büyük harfe dönüştürmenin birkaç yolu vardır.

İlk yol, ilk karakteri kaplayan ve dizenin geri kalanını bir alt dize kullanarak ekleyen bir yöntem oluşturmaktır:

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

İkinci yol (biraz daha hızlıdır) dizeyi bir char dizisine bölmek ve ardından dizeyi yeniden oluşturmaktır:

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

1
Bu çözüm, soruya tam olarak cevap vermiyor. Sorunun başlığı "Tüm ilk harfleri büyük harfe dönüştür, her kelime için daha alta kal" şeklindedir. Bununla birlikte, bu çözüm yalnızca tüm dizenin ilk harfini büyük harf yapar. Bu nedenle, bu çözüm "merhaba dünya" yı "Merhaba Dünya" yerine "Merhaba dünya" olarak dönüştürür.
brsfan

9

Test edilmemiş ancak bunun gibi bir şey çalışmalıdır:

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

Esasen, "başka bir alfasayısal karakteri izleyen bir alfasayısal karakterin tüm oluşumlarında bir normal ifade eşleşmesi önceden oluştur ve ardından onu kendi küçük harfli bir sürümüyle değiştir" diyor


Bu aynı zamanda tüm büyük harfli kelimelerin büyük harfle başlamasını ve küçük harfle devam etmesini sağlar. Tam olarak aradığım şey.
M.Azyoksul

9

Bir web sayfasında kullanıyorsanız, CSS de kullanabilirsiniz:

style="text-transform:capitalize;"


2
Neden CSS? Soru c # asp.net regex istediğinde
Jay

1
Etiket ASP.NETOP'nin bunu WEB'de yaptığını gösterir. Elbette sorunun cevabı bu değil çünkü OP'nin çözüme ihtiyacı var C#ama sorunu çözüyor ve alternatif bir çözüm olabilir. +1
Muhammad Saqib

6

Büyük masalar inşa ederken hız önemli olduğundan Jamie Dixon'ın ikinci işlevi en iyisidir, ancak tamamen olduğu gibi çalışmaz ...

Tüm harfleri küçük harfe çeviremez ve dizedeki her kelimenin ilk harfini değil, dizenin yalnızca ilk harfini büyük yapar ... aşağıdaki seçenek her iki sorunu da giderir:

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

Bu noktada, bunun hala en hızlı seçenek olup olmadığı belirsiz olsa da, RegexGeorge Mauer tarafından sağlanan çözüm daha hızlı olabilir ... yeterince önemseyen birinin test etmesi gerekir.


2
işe yarıyor, ancak bunu "a.Count ()" a.Length olarak değiştirdim
Christian

2

Aşağıdaki çözümün jspcal'ın cevabından daha fazla mı yoksa daha az mı verimli olduğunu bilmiyorum, ancak Jamie ve George'unkinden daha az nesne oluşturma gerektirdiğinden eminim.

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
Nesne oluşturmayla ilgileniyorsak, neden StringBuilder kullanmak yerine s üzerinden for döngüsü indeksleme ile yerinde yapmayalım?
jball

0

İlk cevaba ek olarak, dizge seçimi başlangıç ​​indeksini kelimenin sonuna değiştirmeyi unutmayın, aksi takdirde dizedeki harflerin ters sırasını alırsınız.

s.SelectionStart=s.Length;

0

Bu tekniği deneyin; İstenilen sonucu verir

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

Ve kullanmayı unutma System.Globalization.


0

İlginizi çekebilecek olası çözümlerden biri. Bir döngüde sağdan sola ve tam tersi bir karakter dizisini gezmek.

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

jspcal'ın yanıtı bir dizge uzantısı olarak.

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());
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.