C # 'da ad ve soyadının ilk harfini nasıl büyük yazarım?


141

Bir dizenin ilk harfini büyük yazmanın ve geri kalanını alçaltmanın kolay bir yolu var mı? Yerleşik bir yöntem var mı yoksa kendiminkini yapmam gerekiyor mu?


3
Uygulamanız hakkında hiçbir şey bilmiyorum, ancak genel bir uyarının zamanı geldiğini düşünüyorum: programcılar bu yöntemi gerçek adlara willy-nilly uygulamamalıdır. Sanırım yaşlı John MacDonald, ee cummings, çan kancaları, danah boyd, ah 行 弘, soyadında "von" olan insanlar, soyadı "O'Doyle" olan insanlar, Çoğu isim, büyük / küçük harflerle (ve büyük harfle yazılmış karakterlerle) "İlk Son" biçiminde değildir; Kalzumeus.com/2010/06/17/…
Nick

@Nick kesinlikle haklı. Küçük harfin ardından büyük harfin yanlış olduğunu bile düşünemezsiniz - İrlandalı isimler "A hAirt" gibi şeyler yapar. Herhangi bir kongre için başınızın üstünde düşünebileceğinizi varsayalım, sizi şaşırtacak bir kültür / dil olacak.
James Moore

Yanıtlar:


259

TextInfo.ToTitleCase()dizenin her belirtecindeki ilk karakteri büyük yapar.
Kısaltma Üst Yayınını korumaya gerek yoksa, eklemeniz gerekir ToLower().

string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"

CurrentCulture kullanılamıyorsa, şunu kullanın:

string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());

Ayrıntılı açıklama için MSDN Bağlantısına bakın .


24
Burada dikkat edilmesi gereken bir nokta, dize tamamen büyük harf olduğunda işe yaramıyor. Tüm kapakların bir kısaltma olduğunu düşünüyor.
Mike Roosa

9
Bunların çoğunda gördüğüm şey, onlara güvenemeyeceğiniz. İsim McCain gibi bir şeyse veya daha fazla yabancı isme basmaya başlarsanız işe yaramaz.
Mike Wills

25
@roosa - O ToTitleCase (val.ToLower ()) kolay düzeltme
Simon_Weaver

+1 Zaten FCL'de olması gerektiğini biliyordum ve google beni buraya getirdi = D
gideon

13
Nathan'ın aşağıdaki cevabından farklı olarak bir hata alıyorum: "Statik olmayan alan, yöntem veya özellik ...... için bir nesne referansı gerekiyor." Maalesef.
Dan W

117
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");

Hata! İyi cevap. Küreselleşme konularını hep unutuyorum.
Michael Haren

Harika bir çözüm! sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case
VB.Net'te

Mevcut kültürü değil, her bir ismin kültürünü tespit etmeniz gerekir . Bu isimler için geçerli değildir.
James Moore

1
Bu dayandığı için CurrentCulture, bunu farklı şekilde ele alan bir kültür olmadığından nasıl emin olabiliriz?
Rudey

30
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);

Yukarıdaki kod çalışmaz .....

bu yüzden aşağıdaki kodu dönüştürmek için aşağıya koyun ve işlevi uygulayın

String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());

15

İşleyemeyen bazı durumlar var CultureInfo.CurrentCulture.TextInfo.ToTitleCase, örneğin: kesme işareti '.

string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo

Bir regex , \b[a-zA-Z]bir kelime sınırından sonra bir kelimenin başlangıç ​​karakterini tanımlamak için de kullanılabilir \b, ardından Regex.Replace(string input,string pattern,MatchEvaluator evaluator)yöntem sayesinde eşleşmeyi büyük harf eşdeğeriyle değiştirmemiz gerekir :

string input = "o'reilly, m'grego, d'angelo";
input = Regex.Replace(input.ToLower(), @"\b[a-zA-Z]", m => m.Value.ToUpper());
// input = O'Reilly, M'Grego, D'Angelo

Regex gerekirse biz idare etmek istiyorsanız, örneğin, ayarlanabilir MacDonaldve McFryregex olur vakaları:(?<=\b(?:mc|mac)?)[a-zA-Z]

string input = "o'reilly, m'grego, d'angelo, macdonald's, mcfry";
input = Regex.Replace(input.ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z]", m => m.Value.ToUpper());
// input = O'Reilly, M'Grego, D'Angelo, MacDonald'S, McFry

Biz daha fazla önekleri işlemek gerekiyorsa biz sadece grubu değiştirmek gerekir (?:mc|mac)örnek fransız önekleri eklemek için, du, de: (?:mc|mac|du|de).

Son olarak, bu normal ifadenin de MacDonald'Ssonuncusu için durumla eşleşeceğini anlayabiliriz, bu 'syüzden bunu normal bir ifadeyle olumsuz bir bakışla ele almamız gerekir (?<!'s\b). Sonunda:

string input = "o'reilly, m'grego, d'angelo, macdonald's, mcfry";
input = Regex.Replace(input.ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper());
// input = O'Reilly, M'Grego, D'Angelo, MacDonald's, McFry

@polkduran İsminin sonunda romen rakamlarıyla başa çıkmanın bir yolunu bulmaya çalışıyorum; Hepsini büyük harf yapmak istiyorum: John Smith III. Olumsuz arkaplan buna müdahale eder mi?
Matt

Genellikle olduğu gibi, sonunda kendi soruma cevap verebildim. Romen rakamlarını eşleştirmek için isteğe bağlı bir grup ekledim (üst kasalı olacak). İşte şimdi kullandığım tam regex: (? <= \ B (?: Mc | mac)?) [A-zA-Z] (? <! 'S \ b) (?: ii | iii | iv | v | vi | vii | viii | ix)?
Matt

Durumunuz özel bir sorundur, yanıttaki normal ifade her adı (soyadı) giriş dizesinde (test giriş dizesinin birkaç adı vardır) yalıtılmış bir sözcük olarak ele alır, böylece 'adın sonu' nosyonuna sahip değildir . Tek bir isim olarak girdi dizesi davranırsan size dava ile uğraşmak için basit koşulu ile regex öneki: \b[ivxlcdm]+$|Eğer zorunda \b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b). Sıkı bir romen rakamı biçimine ( ivxlcdm) sahip olmayan bir adın tüm bitiş kelimelerini upercase edecektir . Bununla birlikte, bazı istenmeyen sonuçlarınız olabilir, örneğin 'Li' 'LI' olacak
polkduran

İlginç. Sanırım eklemeniz yapı konusunda muhtemelen daha doğru, ama katılıyorum ... Belirttiğiniz bazı sorunlar olacağını düşünüyorum. Yukarıdaki çözümümde, benim durumumda çalışacak olan "ix" e kadar olan ekleri kodladım ancak herkes için uygun olmayabilir.
Matt

1
@ Si8, test ettin mi? Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())
polkduran

7

Mc ve Mac, ABD genelinde yaygın soyadı önekleridir ve diğerleri de vardır. TextInfo.ToTitleCase bu durumları işlemez ve bu amaçla kullanılmamalıdır. Bunu şu şekilde yapıyorum:

    public static string ToTitleCase(string str)
    {
        string result = str;
        if (!string.IsNullOrEmpty(str))
        {
            var words = str.Split(' ');
            for (int index = 0; index < words.Length; index++)
            {
                var s = words[index];
                if (s.Length > 0)
                {
                    words[index] = s[0].ToString().ToUpper() + s.Substring(1);
                }
            }
            result = string.Join(" ", words);
        }
        return result;
    }


4

En doğrudan seçenek, çoğu zaman adla ilgilenmesi gereken .NET'te bulunan ToTitleCase işlevini kullanmak olacaktır . As edg işaret bazı isimler vardır o için çalışma olmaz, ancak bu tür isimler size çok fazla endişesi bulunabilmeleri için gerekli bir şey değildir yaygındır kültürünü hedef sürece bu oldukça nadir böylece olduklarını.

Bununla birlikte, bir .NET dili ile çalışmıyorsanız, girdinin nasıl göründüğüne bağlıdır - ilk ad ve soyadı için iki ayrı alanınız varsa, ilk harfi büyük harf kullanarak büyük harflerle yazabilirsiniz. altdizgelerin.

firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();

Ancak, aynı dizenin bir parçası olarak birden fazla ad verilirse, bilgileri nasıl aldığınızı bilmeniz ve buna göre bölmeniz gerekir . Eğer "John Doe" gibi bir isim alıyorsanız dizeyi boşluk karakterine göre ayırırsınız. "Doe, John" gibi bir formattaysa, virgül temelinde bölmeniz gerekir. Ancak, parçalara ayrıldıktan sonra daha önce gösterilen kodu uygularsınız.


3

CultureInfo.CurrentCulture.TextInfo.ToTitleCase ("benim adım");

döndürür ~ Benim adım

Ancak sorun, daha önce belirtildiği gibi McFly gibi adlarla hala var.


3
McFry! Konichiwa, Bay Fugitsu-san
Ian Boyd

@David C Boşluğu null ile değiştirmeyi deneyin !! like string.replace ('', '')
Chintan

3

Bunu düzeltmek için kendi yöntemimi kullanın:

Örneğin: "merhaba dünya. Merhaba bu yığın akışı dünyası." "Merhaba Dünya. Merhaba Bu Stackoverflow Dünyası." Regex \ b (kelimenin başlangıcı) \ w (kelimenin ilk karakteri) işinizi görecektir.

/// <summary>
/// Makes each first letter of a word uppercase. The rest will be lowercase
/// </summary>
/// <param name="Phrase"></param>
/// <returns></returns>
public static string FormatWordsWithFirstCapital(string Phrase)
{
     MatchCollection Matches = Regex.Matches(Phrase, "\\b\\w");
     Phrase = Phrase.ToLower();
     foreach (Match Match in Matches)
         Phrase = Phrase.Remove(Match.Index, 1).Insert(Match.Index, Match.Value.ToUpper());

     return Phrase;
}

2

ToTitleCase kullanma önerileri, tümü büyük harf olan dizelerde çalışmaz. Bu yüzden ilk karakterde ToUpper'ı ve kalan karakterlerde ToLower'ı çağırmanız gerekecek.


6
ToTitleCase'i çağırmadan önce neden giriş dizesinde ToLower'ı çağırmıyorsunuz?
Andy Rose

2

Bu sınıf hile yapar. _Prefixes statik dize dizisine yeni önekler ekleyebilirsiniz .

public static class StringExtensions
{
        public static string ToProperCase( this string original )
        {
            if( String.IsNullOrEmpty( original ) )
                return original;

            string result = _properNameRx.Replace( original.ToLower( CultureInfo.CurrentCulture ), HandleWord );
            return result;
        }

        public static string WordToProperCase( this string word )
        {
            if( String.IsNullOrEmpty( word ) )
                return word;

            if( word.Length > 1 )
                return Char.ToUpper( word[0], CultureInfo.CurrentCulture ) + word.Substring( 1 );

            return word.ToUpper( CultureInfo.CurrentCulture );
        }

        private static readonly Regex _properNameRx = new Regex( @"\b(\w+)\b" );
        private static readonly string[] _prefixes = {
                                                         "mc"
                                                     };

        private static string HandleWord( Match m )
        {
            string word = m.Groups[1].Value;

            foreach( string prefix in _prefixes )
            {
                if( word.StartsWith( prefix, StringComparison.CurrentCultureIgnoreCase ) )
                    return prefix.WordToProperCase() + word.Substring( prefix.Length ).WordToProperCase();
            }

            return word.WordToProperCase();
        }
}

1

VS2k8 kullanıyorsanız, bunu String sınıfına eklemek için bir uzantı yöntemi kullanabilirsiniz:

public static string FirstLetterToUpper(this String input)
{
    return input = input.Substring(0, 1).ToUpper() + 
       input.Substring(1, input.Length - 1);
}

9
Char.ToUpper(input[0]) + input.Substring(1)daha okunabilir IMHO.
Hosam Aly

IMHO'ya karşı input.FirstLetterToUpper()kesinlikle daha okunabilirChar.ToUpper(input[0]) + input.Substring(1) , ancak daha az şeffaf
Michael

0

Ben vurgulanan sorunları / sorunları bazı almak için ilk önce dize küçük harf dönüştürme ve sonra ToTitleCase yöntemi çağırmak öneririz. Daha sonra özel dikkat gerektiren özel durumları belirlemek için IndexOf ("Mc") veya IndexOf ("O \ '") kullanabilirsiniz.

inputString = inputString.ToLower();
inputString = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(inputString);
int indexOfMc = inputString.IndexOf(" Mc");
if(indexOfMc  > 0)
{
   inputString.Substring(0, indexOfMc + 3) + inputString[indexOfMc + 3].ToString().ToUpper() + inputString.Substring(indexOfMc + 4);
}

0

Bu şekilde seviyorum:

using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());

Bu MSDN makalesinden kaldırıldı .


0

Umarım bu size yardımcı olur.

String fName = "firstname";
String lName = "lastname";
String capitalizedFName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(fName);
String capitalizedLName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(lName);

0
 public static string ConvertToCaptilize(string input)
        {
            if (!string.IsNullOrEmpty(input))
            {
                string[] arrUserInput = input.Split(' ');


                // Initialize a string builder object for the output
                StringBuilder sbOutPut = new StringBuilder();


                // Loop thru each character in the string array
                foreach (string str in arrUserInput)
                {
                    if (!string.IsNullOrEmpty(str))
                    {
                        var charArray = str.ToCharArray();
                        int k = 0;
                        foreach (var cr in charArray)
                        {
                            char c;
                            c = k == 0 ? char.ToUpper(cr) : char.ToLower(cr);
                            sbOutPut.Append(c);
                            k++;
                        }


                    }
                    sbOutPut.Append(" ");
                }
                return sbOutPut.ToString();
            }
            return string.Empty;

        }

-1

Edg'nin belirttiği gibi, özel adları işlemek için daha karmaşık bir algoritmaya ihtiyacınız olacak (muhtemelen bu yüzden birçok yer her şeyi büyük harfe zorlar).

Bu test edilmemiş c # gibi bir şey, talep ettiğiniz basit durumu ele almalıdır:

public string SentenceCase(string input)
{
    return input(0, 1).ToUpper + input.Substring(1).ToLower;
}

Bunu unutun - globalleşme sınıfını kullanın stackoverflow.com/questions/72831/…
Michael Haren
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.