Coloque a primeira letra de uma string em maiúscula (com desempenho máximo)

447

Eu tenho um DetailsViewcom a TextBox e quero que os dados de entrada sejam salvos sempre com a PRIMEIRA LETRA EM CAPITAL.

Exemplo:

"red" --> "Red"
"red house" --> " Red house"

Como posso obter esse desempenho maximizador ?


NOTA :
Com base nas respostas e nos comentários das respostas, muitas pessoas pensam que isso é perguntar sobre colocar em maiúscula todas as palavras na sequência. Por exemplo => Red House , não é, mas se é isso que você procura , procure uma das respostas que usa TextInfoo ToTitleCasemétodo de. (OBSERVAÇÃO: Essas respostas estão incorretas para a pergunta realmente feita.)
Consulte o documento TextInfo.ToTitleCase para advertências (não toca em letras maiúsculas - elas são consideradas siglas; podem ser minúsculas no meio das palavras que "não deveriam" ser reduzido, por exemplo, "McDonald" => "Mcdonald"; não é garantido o manuseio de todas as sutilezas específicas da cultura quanto às regras de capitalização.)


NOTA :
A questão é ambígua se as letras após a primeira devem ser forçadas a minúsculas . A resposta aceita pressupõe que apenas a primeira letra deve ser alterada . Se você deseja forçar todas as letras da string, exceto a primeira em minúscula, procure uma resposta que contenha ToLowere não contenha ToTitleCase .

dylan-myers
fonte
7
@ Bobby: Não é uma duplicata: o OP pede para colocar em maiúscula a primeira letra de uma string, a pergunta no link coloca em maiúscula a primeira letra de cada palavra.
GvS
1
@GvS: A primeira resposta é muito detalhada e o primeiro bloco de código é exatamente o que ele está procurando. Além disso, entre capitalizar cada palavra e apenas a primeira palavra, há apenas uma diferença de loop.
Bobby
Você já resolveu isso com êxito? Você ainda precisa de ajuda com isso?
jcolebrand
1
Mas você disse, e cito: "Faça a primeira letra de CADA PALAVRA maiúscula". Portanto, por que "casa vermelha" -> "casa vermelha"? Por que o "h" de "casa" não é uma letra maiúscula?
Guillermo Gutiérrez
Foi adicionada uma resposta, pois a maioria das respostas falhará se você tiver um espaço em branco no início. para evitar postar isso em cada resposta, postarei aqui uma vez.
Noctis 22/10

Respostas:

583

Atualizado para C # 8

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
            _ => input.First().ToString().ToUpper() + input.Substring(1)
        };
}

C # 7

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input.First().ToString().ToUpper() + input.Substring(1);
        }
    }
}

Respostas realmente antigas

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
}

EDIT : Esta versão é mais curta. Para uma solução mais rápida, dê uma olhada na resposta da Equiso

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + input.Substring(1);
}

EDIT 2 : Provavelmente a solução mais rápida é a de Darren (há até uma referência), embora eu alterasse sua string.IsNullOrEmpty(s)validação para lançar uma exceção, pois o requisito original espera que uma primeira letra exista para que possa ser maiúscula. Observe que esse código funciona para uma sequência genérica e não particularmente para valores válidos de Textbox.

Carlos Muñoz
fonte
2
Porque o primeiro parâmetro de String.Joiné separador com o qual juntar as strings fornecidas com o segundo parâmetro.
Dialecticus
27
Eu realmente gosto da sua resposta, mas var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);provavelmente ganharia velocidade já que você está criando objetos menos imutáveis ​​(e especialmente você está pulando String.Join). Obviamente, isso depende do comprimento da string.
flindeberg
3
Impressionante - O uso do Linq deixa muito claro o que esse código faz.
Daniel Daniel Bryars
7
Hmmm ... Tecnicamente, isso deve retornar "Argh!"para manter a regra de Primeira Letra Maiúscula . ;)
jp2code
2
@ jp2code Como colocar em maiúscula uma primeira letra inexistente em uma sequência nula ou vazia é como levar um tapa em um golfinho grávida, então o ALL CAPS ARGH! é a ortografia correta. urbandictionary.com/define.php?term=ARGH&defid=67839
Carlos Muñoz
319
public string FirstLetterToUpper(string str)
{
    if (str == null)
        return null;

    if (str.Length > 1)
        return char.ToUpper(str[0]) + str.Substring(1);

    return str.ToUpper();
}

Resposta antiga: isso coloca todas as primeiras letras em maiúsculas

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
Diego Torres
fonte
Mas isso converte todas as primeiras letras de uma palavra em maiúsculas, não apenas o primeiro caractere de uma string.
GvS
@ GvS, é isso que a pergunta pede.
thattolleyguy
17
Ele pergunta "casa vermelha" => "casa vermelha". ToTitleCase lhe dará "Red House".
GvS
1
útil para mim. Ótimo
Ehsan Sajjad
1
Não tenho certeza, mas char + string causa um boxe. Apenas no caso de desempenho máximo é o requisito.
nawfal
163

O caminho certo é usar o Culture:

System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())

Nota: Isso colocará em maiúscula cada palavra em uma sequência, por exemplo "casa vermelha" -> "Casa vermelha". A solução também usará letras minúsculas em palavras, por exemplo, "old McDonald" -> "Old Mcdonald".

Pierre-Yves Guillemet
fonte
4
Esta é a maneira mais adequada de fazê-lo, em vez de reinventar a roda e tentar escrever sua própria versão disso.
Alexey Shevelyov
12
O problema que tenho com isso é que ele limpará letras maiúsculas potencialmente válidas que estão no meio da cadeia. por exemplo McNames
Jecoms
29
Esta é uma resposta incorreta pelo motivo de "casa vermelha" se tornar "casa vermelha" (observe o "H")!
spaark 28/09/16
21
Seis anos após a pergunta, faça um trabalho mais minucioso ao ler as respostas existentes e seus comentários . Se você está convencido de que tem uma solução melhor, mostre as situações em que sua resposta se comporta da maneira que você acha que é superior, e especificamente como isso difere das respostas existentes. 1) Equiso já cobriu esta opção, na segunda metade de sua resposta. 2) Para muitas situações, ToLoweré um erro, pois apaga a capitalização no meio da palavra, por exemplo, "McDonalds". 3) A questão é mudar apenas a primeira palavra da string , não o TitleCase.
Home
10
Isso transforma a entrada em "Título do caso" - para transformar "cavalo vermelho" em "Cavalo vermelho" - enquanto a pessoa que pergunta explicitamente afirma que NÃO deve fazer isso (e retornar "Cavalo vermelho"). Este não é o caminho certo.
Hekkaryk
68

Peguei o método mais rápido em http://www.dotnetperls.com/uppercase-first-letter e converti para o método de extensão:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
    /// </summary>
    public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return string.Empty;

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

NOTA: O motivo pelo qual o uso ToCharArrayé mais rápido que a alternativa char.ToUpper(s[0]) + s.Substring(1)é que apenas uma string é alocada, enquanto a Substringabordagem aloca uma string para a substring e, em seguida, uma segunda string para compor o resultado final.


EDIT : Aqui está a aparência dessa abordagem, combinada com o teste inicial de CarlosMuñoz, resposta aceita :

    /// <summary>
    /// Returns the input string with the first character converted to uppercase
    /// </summary>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrEmpty(s))
            throw new ArgumentException("There is no first letter");

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }
Darren
fonte
Uau, obrigado por encontrar métricas de desempenho, para mostrar uma solução de desempenho superior!
Home
@ ToolmakerSteve, eu gosto desta solução, pois ela parece mais rápida do que outras, mas há um pequeno problema com isso. Se você passar nulo, não deverá obter uma sequência vazia como saída. Na verdade, eu argumentaria que mesmo passar uma string vazia deve gerar uma exceção, já que o OP solicita a primeira letra. Além disso, você pode comentar a resposta de outras pessoas antes de editá-las.
Carlos Muñoz
@ CarlosMuñoz - foi discutido na meta, se "melhorar" as respostas de outras pessoas. O consenso era "se você pode melhorar uma resposta, faça-o - ninguém 'possui' uma resposta, nem mesmo o autor original - o objetivo é ter as melhores respostas possíveis". Você é livre para editar ou reverter a edição. Nesse caso, a cortesia comum permitiria que a versão do autor original fosse o resultado final, e eu gostaria de comentar. Normalmente, também faço um comentário sobre a alteração que estou fazendo; Peço desculpas se não o fiz.
Home
@ CarlosMuñoz - em particular, existem muitas, muitas respostas no SO, que não são mantidas ativamente. Se uma mudança melhoraria uma resposta, por que deixá-la enterrada em um comentário? Se o autor estiver monitorando ativamente suas respostas, fará a alteração como achar melhor. Caso contrário, a resposta foi melhorada, para benefício de todos. Esse princípio é especialmente verdadeiro para perguntas e respostas antigas, como esta.
Home
BTW, eu concordo com o @ CarlosMuñoz sobre o teste no início do método - sua versão desse teste tem um estilo de programação melhor - return string.Emptyaqui ocultaria uma chamada "ruim" ao método.
Home
46

Você pode usar o "método ToTitleCase"

string s = new CultureInfo("en-US").TextInfo.ToTitleCase("red house");
//result : Red House

este método de extensão resolve todos os problemas de titlecase.

fácil de usar

string str = "red house";
str.ToTitleCase();
//result : Red house

string str = "red house";
str.ToTitleCase(TitleCase.All);
//result : Red House

o método de extensão

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Test
{
    public static class StringHelper
    {
        private static CultureInfo ci = new CultureInfo("en-US");
        //Convert all first latter
        public static string ToTitleCase(this string str)
        {
            str = str.ToLower();
            var strArray = str.Split(' ');
            if (strArray.Length > 1)
            {
                strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                return string.Join(" ", strArray);
            }
            return ci.TextInfo.ToTitleCase(str);
        }
        public static string ToTitleCase(this string str, TitleCase tcase)
        {
            str = str.ToLower();
            switch (tcase)
            {
                case TitleCase.First:
                    var strArray = str.Split(' ');
                    if (strArray.Length > 1)
                    {
                        strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                        return string.Join(" ", strArray);
                    }
                    break;
                case TitleCase.All:
                    return ci.TextInfo.ToTitleCase(str);
                default:
                    break;
            }
            return ci.TextInfo.ToTitleCase(str);
        }
    }

    public enum TitleCase
    {
        First,
        All
    }
}
İbrahim Özbölük
fonte
O problema com sua solução é que "casa vermelha" será convertida em "casa vermelha" e não em "casa vermelha", conforme solicitado na pergunta.
Vadim
3
@Tacttin Funcionará, mas o código a seguir é mais fácil de ler e executa melhor char.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ; Você pode ler mais @ vkreynin.wordpress.com/2013/10/09/…
Vadim
1
Não gosto desta solução, porque combina duas situações bastante diferentes em um método demorado. Também não vejo um benefício conceitual. E a implementação de capitalizar apenas a primeira letra é .. ridícula. Se você deseja colocar em maiúscula a primeira letra, a implementação óbvia é apenas colocar em maiúscula (ToUpper) a primeira letra . Em vez disso, eu teria dois métodos separados. FirstLetterToUpperna resposta de Equiso (ou na resposta mais recente de Guillernet) e ToTitleCaseaqui, mas sem o segundo parâmetro. Então não precisa enum TitleCase.
Home
31

Para a primeira letra, com verificação de erros:

public string CapitalizeFirstLetter(string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}

E aqui está o mesmo que uma extensão útil

public static string CapitalizeFirstLetter(this string s)
    {
    if (String.IsNullOrEmpty(s)) return s;
    if (s.Length == 1) return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
    }
Kobi
fonte
Abordagem limpa. Obrigado!
Philippe
11
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}
Big T
fonte
6

Se o desempenho / uso da memória for um problema, este criará apenas um (1) StringBuilder e um (1) novo String do mesmo tamanho que o String original.

public static string ToUpperFirst(this string str) {
  if( !string.IsNullOrEmpty( str ) ) {
    StringBuilder sb = new StringBuilder(str);
    sb[0] = char.ToUpper(sb[0]);

    return sb.ToString();

  } else return str;
}
Daniel Halan
fonte
3
Isso pode ser feito com um simples, em char[]vez de ter toda a infraestrutura de um StringBuilderempacotamento. Em vez de new StringBuilder(str), use str.ToCharArray()e em vez de sb.ToString(), use new string(charArray). StringBuilderemula o tipo de indexação que uma matriz de caracteres expõe nativamente, para que a .ToUpperlinha real possa ser essencialmente a mesma. :-)
Jonathan Gilbert
Darren (um ano depois) mostra como fazer isso usando ToCharArray, como sugerido porJonathanGilbert
ToolmakerSteve
6

Método mais rápido.

  private string Capitalize(string s){
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
}

Os testes mostram os próximos resultados (sequência com 10000000 símbolos como entrada): Resultados do teste

Александр Иванов
fonte
1
Eu recomendo retornar o sparâmetro quando nulo ou vazio.
MatrixRonny
4

Tente o seguinte:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}
JoelFan
fonte
2
ou talvez alguma outra classe de personagem (ou seja alfanumérico \ w), para que a função é Unicode-aware
Dmitry Ledentsov
@ DmitryLedentsov- A classe de string C # é criada com caracteres UTF-16. Classe de seqüência de caracteres "Representa o texto como uma sequência de unidades de código UTF-16."
Página
4

Se você se importa apenas com a primeira letra em maiúscula e não importa o restante da sequência, basta selecionar o primeiro caractere, colocá-lo em maiúscula e concatená-lo com o restante da sequência sem o primeiro caractere original.

String word ="red house";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = "Red house"

Precisamos converter o primeiro caractere ToString () porque o estamos lendo como uma matriz Char, e o tipo Char não possui o método ToUpper ().

Víctor García
fonte
3

Aqui está uma maneira de fazer isso como um método de extensão:

static public string UpperCaseFirstCharacter(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        return string.Format(
            "{0}{1}",
            text.Substring(0, 1).ToUpper(),
            text.Substring(1));
    }

    return text;
}

Pode então ser chamado como:

//yields "This is Brian's test.":
"this is Brian's test.".UpperCaseFirstCharacter(); 

E aqui estão alguns testes de unidade para isso:

[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
    string orig = "";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(orig, result);
}

[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
    string orig = "c";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("C", result);
}

[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
    string orig = "this is Brian's test.";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("This is Brian's test.", result);
}
bingles
fonte
1
string.Formaté um exagero; simplesmente faça text.Substring(0, 1).ToUpper() + text.Substring(1).
Home
3

Desde que eu estava trabalhando nisso também, e estava procurando idéias, essa foi a solução que encontrei. Ele usa o LINQ e poderá capitalizar a primeira letra de uma sequência, mesmo que a primeira ocorrência não seja uma letra. Aqui está o método de extensão que acabei fazendo.

public static string CaptalizeFirstLetter(this string data)
{
    var chars = data.ToCharArray();

    // Find the Index of the first letter
    var charac = data.First(char.IsLetter);
    var i = data.IndexOf(charac);

    // capitalize that letter
    chars[i] = char.ToUpper(chars[i]);

    return new string(chars);
}

Tenho certeza de que há uma maneira de otimizar ou limpar isso um pouco.

CAOakley
fonte
3

Encontrei algo aqui http://www.dotnetperls.com/uppercase-first-letter :

static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
    return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}

talvez isso ajude !!

Mohammed Zameer
fonte
Como isso é uma melhoria em relação à resposta da Equiso 4 anos antes?
Página
3

Verifique se a sequência não é nula e converta o primeiro caractere para maiúsculas e o restante para minúsculas:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}
mbadeveloper
fonte
Obrigado pela solução pequena, em vez de poucas linhas de código, apenas por uma palavra de string!
Imran Faruqi 22/01
2

Isso será feito, mas também garantirá que não haja maiúsculas erradas que não estejam no início da palavra.

public string(string s)
{
System.Globalization.CultureInfo c = new System.Globalization.CultureInfo("en-us", false)
System.Globalization.TextInfo t = c.TextInfo;

return t.ToTitleCase(s);
}
Jeff Hornby
fonte
2
Precisa de uma verificação nula santes da chamada para ToTitleCase.
Taras Alenin
@ CarlosMuñoz tlhIngan Hol não possui letras maiúsculas no seu script. :-) #
Jonathan Gilbert
2

Parece haver muita complexidade aqui quando tudo que você precisa é:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase if a letter
    /// </summary>
    /// <remarks>Null input returns null</remarks>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrWhiteSpace(s))
            return s;

        return char.ToUpper(s[0]) + s.Substring(1);
    }

Pontos dignos de nota:

  1. É um método de extensão.

  2. Se a entrada for nula, em branco ou em branco, a entrada será retornada como está.

  3. String.IsNullOrWhiteSpace foi introduzido no .NET Framework 4. Isso não funcionará com estruturas mais antigas.

Stephen Kennedy
fonte
1
Não vejo como isso é uma melhoria na resposta original aceita de quatro anos atrás. Na verdade, é inconsistente (inofensiva assim, mas quatro anos de atraso, eu tenho altos padrões para uma nova resposta benefício adicionando): A única vantagem de usar o mais recente IsNullOrWhiteSpaceem vez de IsNullOrEmpty, é que se você está indo para encontrar e alterar o primeiro não- espaço em branco . Mas você não - você sempre opera s[0]. Portanto, é inútil usar [semântica e desempenho] IsNullOrWhiteSpace.
Home
... por que esse uso IsNullOrWhiteSpaceme incomoda, é que um leitor descuidado pode pensar "Ele checou o espaço em branco, para que o código a seguir encontre e mude realmente uma letra, mesmo que seja precedida por espaço em branco". Como seu código falhará ao alterar uma "primeira" letra precedida por espaço em branco, o uso IsNullOrWhiteSpacepoderá enganar apenas um leitor.
Home
... opa, não quero dizer a resposta aceita, quero dizer a resposta da Equiso no mesmo período.
Home
1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();
Shailesh
fonte
Por que ToLower () na cauda ?. Não há requisito para outras letras, mas a primeira.
Carlos Muñoz
Stringis pode ser qualquer coisa sua Upperou Lower. então é uma solução genérica para todas as strings.
Shailesh #
Por que ao Joininvés de emp.First().ToString().ToUpper() + emp.Substring(1);? Provavelmente precisa ser mais defensivo também: output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Além disso, fwiw, concorde com @ CarlosMuñoz - você não precisa ToLower()da pergunta do OP.
Ruffin
@ ruffin -> using Substring também é um bom estilo de código de escrita, eu concordo que sua solução para aparar um código, mas nesse caso escrever um ToLower()é uma boa prática de programação. stringpode ser qualquer coisa UpperCaso ou Lowercaso dependa da entrada do usuário, eu dou uma solução genérica.
Shailesh
@ Shailesh - No entanto, a pergunta não solicitou que apenas a primeira letra fosse maiúscula. Ele pediu que a primeira letra fosse alterada para ser uma capital. Sem maiores esclarecimentos do autor, a suposição mais natural é que o restante da cadeia de caracteres seja inalterado. Como você responde três anos depois , suponha que a resposta aceita faça o que o solicitante solicitou. Dê uma resposta diferente apenas se houver algum motivo técnico para fazê-lo de maneira diferente.
Home
1

Eu queria fornecer uma resposta "DESEMPENHO MÁXIMO". Na minha opinião, uma resposta de "DESEMPENHO MÁXIMO" captura todos os cenários e fornece a resposta para a pergunta que representa esses cenários. Então, aqui está a minha resposta. Por estes motivos:

  1. IsNullOrWhiteSpace responde por seqüências de caracteres que são apenas espaços ou nulos / vazios.
  2. .Trim () remove os espaços em branco da frente e de trás da string.
  3. .First () pega o primeiro caractere de um número inumerável (ou string).
  4. Devemos verificar se é uma letra que pode / deve estar em maiúscula.
  5. Em seguida, adicionamos o restante da string, apenas se o comprimento indicar que deveríamos.
  6. Por melhores práticas .Net, devemos fornecer uma cultura em System.Globalization.CultureInfo.
  7. Fornecê-los como parâmetros opcionais torna esse método totalmente reutilizável, sem a necessidade de digitar a cultura escolhida todas as vezes.

    public static string capString(string instring, string culture = "en-US", bool useSystem = false)
    {
        string outstring;
        if (String.IsNullOrWhiteSpace(instring))
        {
            return "";
        }
        instring = instring.Trim();
        char thisletter = instring.First();
        if (!char.IsLetter(thisletter))
        {
            return instring;   
        }
        outstring = thisletter.ToString().ToUpper(new CultureInfo(culture, useSystem));
        if (instring.Length > 1)
        {
            outstring += instring.Substring(1);
        }
        return outstring;
    }
Patrick Knott
fonte
2
Embora isso cubra a maioria dos casos, não seria um pouco lento, considerando o número de strings sendo criadas com cada operação? Há uma tonelada de alocação de string acontecendo aqui. De preferência, seria alocado uma vez e apenas uma vez.
Douglas Gaskell
1

Recentemente, tive um requisito semelhante e lembrei que a função LINQ Select () fornece um índice:

string input;
string output;

input = "red house";
output = String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
//output = "Red house"

Como eu preciso muito disso, criei um método de extensão para o tipo de string:

public static class StringExtensions
{
    public static string FirstLetterToUpper(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return string.Empty;
        return String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
    }
}

Observe que apenas a primeira letra é convertida para maiúscula - todos os caracteres restantes não são tocados. Se você precisar que os outros caracteres sejam minúsculos, também pode chamar Char.ToLower (currentChar) para o índice> 0 ou chamar ToLower () em toda a cadeia de caracteres em primeiro lugar.

Em relação ao desempenho, comparei o código com a solução de Darren. Na minha máquina, o código de Darren é cerca de duas vezes mais rápido, o que não é surpresa, pois ele está editando diretamente apenas a primeira letra em uma matriz de caracteres. Então, sugiro que você use o código de Darren se precisar da solução mais rápida disponível. Se você deseja integrar outras manipulações de string, pode ser conveniente ter o poder expressivo de uma função lambda tocando os caracteres da string de entrada - você pode facilmente estender essa função -, então deixo esta solução aqui.

Grimm
fonte
Fiquei pensando em como resolver esse problema, resolvi minha própria solução e voltei a publicá-la apenas para descobrir que você tinha encontrado exatamente a mesma solução que eu já tinha. +1 para você!
BlueFuzzyThing
Muito obrigado.
Grimm
1

Eu acho que o método abaixo é a melhor solução

    class Program
{
    static string UppercaseWords(string value)
    {
        char[] array = value.ToCharArray();
        // Handle the first letter in the string.
        if (array.Length >= 1)
        {
            if (char.IsLower(array[0]))
            {
                array[0] = char.ToUpper(array[0]);
            }
        }
        // Scan through the letters, checking for spaces.
        // ... Uppercase the lowercase letters following spaces.
        for (int i = 1; i < array.Length; i++)
        {
            if (array[i - 1] == ' ')
            {
                if (char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
        }
        return new string(array);
    }

    static void Main()
    {
        // Uppercase words in these strings.
        const string value1 = "something in the way";
        const string value2 = "dot net PERLS";
        const string value3 = "String_two;three";
        const string value4 = " sam";
        // ... Compute the uppercase strings.
        Console.WriteLine(UppercaseWords(value1));
        Console.WriteLine(UppercaseWords(value2));
        Console.WriteLine(UppercaseWords(value3));
        Console.WriteLine(UppercaseWords(value4));
    }
}

Output

Something In The Way
Dot Net PERLS
String_two;three
 Sam

ref

D.JCode
fonte
1

Como esta pergunta é sobre maximizar o desempenho , adotei a versão de Darren para usar Spans, o que reduz o lixo e melhora a velocidade em cerca de 10%.

        /// <summary>
        /// Returns the input string with the first character converted to uppercase
        /// </summary>
        public static string ToUpperFirst(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }

atuação

|  Method |      Data |      Mean |     Error |    StdDev |
|-------- |---------- |----------:|----------:|----------:|
|  Carlos |       red | 107.29 ns | 2.2401 ns | 3.9234 ns |
|  Darren |       red |  30.93 ns | 0.9228 ns | 0.8632 ns |
| Marcell |       red |  26.99 ns | 0.3902 ns | 0.3459 ns |
|  Carlos | red house | 106.78 ns | 1.9713 ns | 1.8439 ns |
|  Darren | red house |  32.49 ns | 0.4253 ns | 0.3978 ns |
| Marcell | red house |  27.37 ns | 0.3888 ns | 0.3637 ns |

Código de teste completo

using System;
using System.Linq;

using BenchmarkDotNet.Attributes;

namespace CorePerformanceTest
{
    public class StringUpperTest
    {
        [Params("red", "red house")]
        public string Data;

        [Benchmark]
        public string Carlos() => Data.Carlos();

        [Benchmark]
        public string Darren() => Data.Darren();

        [Benchmark]
        public string Marcell() => Data.Marcell();
    }

    internal static class StringExtensions
    {
        public static string Carlos(this string input) =>
            input switch
            {
                null => throw new ArgumentNullException(nameof(input)),
                "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
                _ => input.First().ToString().ToUpper() + input.Substring(1)
            };

        public static string Darren(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

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

        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }
    }

}

Edit: Houve um typeo, em vez de s [0], foi um [0] - isso resulta com o mesmo valor vazio para o Span alocado a.

Marcell Toth
fonte
0

Isso coloca em maiúscula essa primeira letra e todas as letras após um espaço e em minúsculas qualquer outra letra.

public string CapitalizeFirstLetterAfterSpace(string input)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);
    bool capitalizeNextLetter = true;
    for(int pos = 0; pos < sb.Length; pos++)
    {
        if(capitalizeNextLetter)
        {
            sb[pos]=System.Char.ToUpper(sb[pos]);
            capitalizeNextLetter = false;
        }
        else
        {
            sb[pos]=System.Char.ToLower(sb[pos]);
        }

        if(sb[pos]=' ')
        {
            capitalizeNextLetter=true;
        }
    }
}
thattolleyguy
fonte
1
Ou se você não quiser escrever paredes de código - CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); faz a mesma coisa.
Chev
Sim ... eu não sabia disso :) E devido à minha enorme quantidade de código, as respostas de todos apareceram enquanto eu ainda estava digitando.
thattolleyguy
AVANÇADO: 1) Uma pequena diferença entre esta resposta e o ToTitleCase é que essa resposta força as palavras com maiúsculas a se tornarem TitleCase, enquanto o ToTitleCase deixa essas palavras em paz (pressupõe que possam ser acrônimos). Isso pode ou não ser o que é desejado. Uma vantagem de ter um exemplo de código como esse é que ele pode ser modificado conforme desejado. 2) isso não manipulará espaços em branco que não sejam '' corretamente. deve substituir o teste em branco pelo teste de espaço em branco.
Home
0

Use o seguinte código:

string  strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();
Prashant Banavali
fonte
Nem vale a pena apontar para o meu representante a votação negativa dessa resposta, adicionada anos depois, que é obviamente equivalente a respostas já existentes. Se você deseja adicionar uma nova resposta a uma pergunta com muitas respostas, explique o que você considera superior em sua resposta ou em que circunstâncias sua resposta seria mais útil do que outras respostas. Seja específico.
Página Inicial>
0

Parece que nenhuma das soluções fornecidas aqui tratará de um espaço em branco antes da string.

Apenas adicionando isso como um pensamento:

public static string SetFirstCharUpper2(string aValue, bool aIgonreLeadingSpaces = true)
{
    if (string.IsNullOrWhiteSpace(aValue))
        return aValue;

    string trimmed = aIgonreLeadingSpaces 
           ? aValue.TrimStart() 
           : aValue;

    return char.ToUpper(trimmed[0]) + trimmed.Substring(1);
}   

Ele deve ser manipulado this won't work on other answers(essa frase tem um espaço no começo) e, se você não gostar do corte de espaço, basta passar o falsesegundo parâmetro (ou alterar o padrão para falsee passar truese quiser lidar com o espaço)

Noctis
fonte
0

A maneira mais fácil de capitalizar a primeira letra é:

1- Usando Sytem.Globalization;

  // Creates a TextInfo based on the "en-US" culture.
  TextInfo myTI = new CultureInfo("en-US",false).

  myTI.ToTitleCase(textboxname.Text)

`

Saad Khalid
fonte
1
Essa resposta é essencialmente idêntica às respostas dadas anos antes. Não acrescenta nada à discussão.
Home
Também está errado, assim como o comentário na outra, isso transforma todas as primeiras letras em todas as palavras maiúsculas, ou seja, Casa Vermelha em vez de Casa Vermelha.
DeadlyChambers
0

a seguinte função está correta em todos os aspectos:

static string UppercaseWords(string value)
{
    char[] array = value.ToCharArray();
    // Handle the first letter in the string.
    if (array.Length >= 1)
    {
        if (char.IsLower(array[0]))
        {
            array[0] = char.ToUpper(array[0]);
        }
    }
    // Scan through the letters, checking for spaces.
    // ... Uppercase the lowercase letters following spaces.
    for (int i = 1; i < array.Length; i++)
    {
        if (array[i - 1] == ' ')
        {
            if (char.IsLower(array[i]))
            {
                array[i] = char.ToUpper(array[i]);
            }
        }
    }
    return new string(array);
}

Eu achei isso aqui


fonte
Por quê? Por que adicionar mais uma resposta quando já existem tantas respostas que parecem semelhantes? O que há de errado com todas as respostas existentes, que solicitaram que você adicionasse outra?
Home
Porque esse answare está correto para todos os aspectos. Se acalme.
Sinto muito; Eu fui desnecessariamente duro. Vou me ater aos fatos: 1) Isso é essencialmente o mesmo que a resposta do bonde sete anos antes. 2) Isso tem a mesma falha que a resposta: não lida com espaços em branco que não sejam caracteres em branco. 3) Isso responde a uma pergunta um pouco diferente da que o OP estava fazendo. Use uma resposta como esta se quiser que todas as palavras tenham a primeira letra em maiúscula. 4) Geralmente, a maneira mais simples de fazer isso é usar TitleInfo.ToTitleCase. (Por outro lado, uma vantagem do amostra de código é possível personalizar o desejar.)
ToolmakerSteve
Corrigindo a mim mesmo: isso é diferente da abordagem do bonde: deixa letras intocadas que não são a primeira letra da palavra. Em vez disso, é uma duplicata da resposta de zamoldar . Favoravelmente, parabéns a Darian por fornecer o link para a fonte - parece zamoldar plagiado sem dar crédito. Por fornecer esse link de origem e, assim, melhorar a discussão , estou votando positivamente nessa resposta, apesar das minhas críticas.
Home
1
Darian, duas melhorias que poderiam ser feitas: 1) use em char.IsWhiteSpace( array[ i -1 ] )vez de .. == ' ', para lidar com todo o espaço em branco. 2) remova os dois lugares que o fazem if (char.isLower(..))- eles não servem para nada. ToUppersimplesmente não faz nada se um personagem não estiver em minúsculas.
Home
0

Expandindo a pergunta de Carlos acima, se você quiser capitalizar várias frases, use este código:

    /// <summary>
    /// Capitalize first letter of every sentence. 
    /// </summary>
    /// <param name="inputSting"></param>
    /// <returns></returns>
    public string CapitalizeSentences (string inputSting)
    {
        string result = string.Empty;
        if (!string.IsNullOrEmpty(inputSting))
        {
            string[] sentences = inputSting.Split('.');

            foreach (string sentence in sentences)
            {
                result += string.Format ("{0}{1}.", sentence.First().ToString().ToUpper(), sentence.Substring(1)); 
            }
        }

        return result; 
    }
Zamir
fonte
0

Solução possível para resolver seu problema.

   public static string FirstToUpper(this string lowerWord)
   {
       if (string.IsNullOrWhiteSpace(lowerWord) || string.IsNullOrEmpty(lowerWord))
            return lowerWord;
       return new StringBuilder(lowerWord.Substring(0, 1).ToUpper())
                 .Append(lowerWord.Substring(1))
                 .ToString();
   }
sayah imad
fonte