Haga la primera letra de una cadena en mayúscula (con el máximo rendimiento)

447

Tengo un DetailsViewcon TextBox ay quiero que los datos de entrada se guarden siempre con la PRIMERA CARTA EN CAPITAL.

Ejemplo:

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

¿Cómo puedo lograr este rendimiento maximizador ?


NOTA :
Según las respuestas y los comentarios que figuran debajo de las respuestas, muchas personas piensan que se trata de poner en mayúscula todas las palabras de la cadena. Por ejemplo => Red House , no lo es, pero si eso es lo que busca , busque una de las respuestas que utiliza TextInfoel ToTitleCasemétodo. (NOTA: Esas respuestas son incorrectas para la pregunta realmente formulada).
Consulte el documento TextInfo.ToTitleCase para ver las advertencias (no toca las palabras en mayúsculas; se consideran siglas; pueden aparecer letras minúsculas en el medio de las palabras que "no deberían" ser reducido, por ejemplo, "McDonald" => "Mcdonald"; no se garantiza que maneje todas las sutilezas específicas de la cultura con respecto a las reglas de capitalización).


NOTA :
La pregunta es ambigua en cuanto a si las letras después de la primera deben ser forzadas a minúsculas . La respuesta aceptada supone que solo la primera letra debe ser alterada . Si desea forzar todas las letras en la cadena, excepto las primeras en minúsculas, busque una respuesta que contenga ToLowery no contenga ToTitleCase .

dylan-myers
fuente
77
@Bobby: No es un duplicado: el OP pide poner en mayúscula la primera letra de una cadena, la pregunta en el enlace escribe en mayúscula la primera letra de cada palabra.
GvS
1
@GvS: La primera respuesta es muy detallada y el primer bloque de código es exactamente lo que está buscando. Además, entre poner en mayúscula cada palabra y solo la primera palabra es solo una diferencia de bucle.
Bobby
¿Alguna vez resolvió esto con éxito? ¿Aún necesitas ayuda con esto?
jcolebrand
1
Pero usted dijo y cito: "Escriba la primera letra de CADA PALABRA mayúscula". Por lo tanto, ¿por qué "casa roja" -> "Casa roja"? ¿Por qué la "h" de "casa" no es una letra mayúscula?
Guillermo Gutiérrez
Se agregó una respuesta ya que la mayoría de las respuestas fallarán si tiene un espacio en blanco al comienzo. para evitar publicar esto en cada respuesta, lo publicaré aquí una vez.
Noctis

Respuestas:

583

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

Respuestas muy viejas

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

EDITAR : Esta versión es más corta. Para una solución más rápida, eche un vistazo a la respuesta de 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 : Probablemente la solución más rápida es la de Darren (incluso hay un punto de referencia), aunque cambiaría su string.IsNullOrEmpty(s)validación para lanzar una excepción, ya que el requisito original espera que exista una primera letra para que pueda ser mayúscula. Tenga en cuenta que este código funciona para una cadena genérica y no particularmente en valores válidos de Textbox.

Carlos Muñoz
fuente
2
Porque el primer parámetro de String.Joines un separador con el cual unir cadenas dadas con el segundo parámetro.
Dialecticus
27
Realmente me gusta su respuesta, pero var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);probablemente ganaría algo de velocidad ya que está creando objetos menos inmutables (y especialmente se está saltando el String.Join). Esto, por supuesto, depende de la longitud de la cadena.
flindeberg
3
Impresionante: el uso de Linq deja muy claro lo que hace este código.
Daniel James Bryars el
77
Hmmm ... Técnicamente, esto debería volver "Argh!"a cumplir con la regla de la primera letra mayúscula. ;)
jp2code
2
@ jp2code Dado que poner en mayúscula una primera letra inexistente en una cadena nula o vacía es como ser abofeteado por un delfín embarazado, ¡entonces ARGH ALL CAPS! Es la ortografía correcta. 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();
}

Respuesta anterior: Esto hace que cada primera letra en mayúscula

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
Diego Torres
fuente
Pero esto convierte cada primera letra de una palabra a mayúsculas, no solo el primer carácter de una cadena.
GvS
@GvS, eso es lo que la pregunta te pide que hagas.
thattolleyguy
17
Él pregunta "casa roja" => "Casa roja". ToTitleCase te dará "Casa Roja".
GvS
1
útil para mi Genial
Ehsan Sajjad
1
No estoy seguro de esto, pero char + string causa un boxeo. Por si acaso el rendimiento máximo es el requisito.
nawfal
163

La forma correcta es usar Cultura:

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

Nota: Esto capitalizará cada palabra dentro de una cadena, por ejemplo, "casa roja" -> "Casa roja". La solución también incluirá mayúsculas en minúsculas en palabras, por ejemplo, "Old McDonald" -> "Old Mcdonald".

Pierre-Yves Guillemet
fuente
44
Esta es la forma más adecuada de hacerlo en lugar de reinventar la rueda e intentar escribir su propia versión de esto.
Alexey Shevelyov
12
El problema que tengo con esto es que borrará las letras mayúsculas potencialmente válidas que están a mitad de cadena. por ejemplo, McNames
Jecoms
29
¡Esta es una respuesta incorrecta por la razón de que "casa roja" se convierte en "Casa Roja" (observe la "H")!
spaark
21
Seis años después de que se hizo la pregunta, lea detenidamente las respuestas existentes y sus comentarios . Si está convencido de que tiene una mejor solución, muestre las situaciones en las que su respuesta se comporta de una manera que cree que es superior, y específicamente cómo difiere de las respuestas existentes. 1) Equiso ya cubrió esta opción, en la segunda mitad de su respuesta. 2) Para muchas situaciones, ToLoweres un error, ya que borra las mayúsculas en la mitad de la palabra, por ejemplo, "McDonalds". 3) La pregunta es sobre cambiar solo la primera palabra de la cadena , no sobre TitleCase.
ToolmakerSteve
10
Esto convierte la entrada en "Caso de título", por lo que convierte "caballo rojo" en "Caballo rojo", mientras que la persona que pregunta explícitamente declaró que NO debería hacer esto (y devolver "Caballo rojo"). Este no es el camino correcto.
Hekkaryk
68

Tomé el método más rápido de http://www.dotnetperls.com/uppercase-first-letter y lo convertí al método de extensión:

    /// <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: La razón por la que el uso ToCharArrayes más rápido que la alternativa char.ToUpper(s[0]) + s.Substring(1)es que solo se asigna una cadena, mientras que el Substringenfoque asigna una cadena para la subcadena, luego una segunda cadena para componer el resultado final.


EDITAR : así es como se ve este enfoque, combinado con la prueba inicial de CarlosMuñoz acepta la respuesta :

    /// <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
fuente
¡Guau, gracias por encontrar métricas de rendimiento, para mostrar una solución de rendimiento superior!
ToolmakerSteve
@ToolmakerSteve, me gusta esta solución, ya que de hecho parece más rápida que otras, pero hay un pequeño problema con esto. Si pasa nulo, no debería obtener una cadena vacía como salida. De hecho, argumentaría que incluso pasar una cadena vacía debería arrojar una excepción, ya que el OP solicita la primera letra. Además, puede comentar las respuestas de otras personas antes de editarlas.
Carlos Muñoz
@ CarlosMuñoz: se ha discutido en meta si se debe "mejorar" las respuestas de otras personas. El consenso fue "si puedes mejorar una respuesta, entonces hazlo, nadie 'posee' una respuesta, ni siquiera el autor original, el objetivo es tener las mejores respuestas posibles". Por supuesto, puede editar o revertir la edición. En cuyo caso, la cortesía común permitiría que la versión original del autor sea el resultado final, y me conformaría con comentar. Por lo general, también pongo en un comentario el cambio que estoy haciendo; Pido disculpas si no lo hice.
ToolmakerSteve
@ CarlosMuñoz: en particular, hay muchas, muchas respuestas en SO, que no se mantienen activamente. Si un cambio mejoraría una respuesta, ¿por qué dejarlo enterrado en un comentario? Si el autor está monitoreando activamente sus respuestas, lo harán con el cambio como mejor les parezca. Si no lo son, la respuesta ha sido mejorada, para beneficio de todos. Este principio es especialmente cierto para preguntas y respuestas antiguas, como esta.
ToolmakerSteve
Por cierto, estoy de acuerdo con @CarlosMuñoz acerca de la prueba al comienzo del método, su versión de esa prueba es un mejor estilo de programación, return string.Emptyaquí escondería una llamada "mala" al método.
ToolmakerSteve
46

Puede usar el "método ToTitleCase"

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

Este método de extensión resuelve todos los problemas de título.

fácil de usar

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

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

el método de extensión

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
fuente
El problema con su solución es que "casa roja" se convertirá en "Casa Roja" y no en "Casa Roja" como se hizo en la pregunta.
Vadim
3
@Tacttin Funcionará, pero el siguiente código es más fácil de leer y funciona mejor char.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ; Puede leer más @ vkreynin.wordpress.com/2013/10/09/…
Vadim
1
No me gusta esta solución, porque combina dos situaciones muy diferentes en un método largo. Tampoco veo un beneficio conceptual. Y la implementación de capitalizar solo la primera letra es ... ridícula. Si desea poner en mayúscula la primera letra, la implementación obvia es simplemente poner en mayúscula (ToUpper) la primera letra . En lugar de esto, tendría dos métodos separados. FirstLetterToUpperen la respuesta de Equiso (o en la respuesta más reciente de Guillernet), y ToTitleCaseaquí, pero sin el segundo parámetro. Entonces no es necesario enum TitleCase.
ToolmakerSteve
31

Para la primera letra, con comprobación de errores:

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

Y esto es lo mismo que una práctica extensión

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
fuente
Enfoque limpio. ¡Gracias!
Philippe
11
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

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

Si el rendimiento / uso de la memoria es un problema, entonces este solo crea un (1) StringBuilder y una (1) nueva cadena del mismo tamaño que la cadena 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
fuente
3
Esto podría hacerse con un simple en char[]lugar de tener toda la infraestructura de una StringBuilderenvoltura. En lugar de new StringBuilder(str)usar str.ToCharArray()y en lugar de sb.ToString()usar new string(charArray). StringBuilderemula el tipo de indexación que una matriz de caracteres expone de forma nativa, por lo que la .ToUpperlínea real puede ser esencialmente la misma. :-)
Jonathan Gilbert
Darren (un año después) muestra cómo hacer esto usando ToCharArray, como lo sugiere @JonathanGilbert
ToolmakerSteve
6

Método más 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);
}

Las pruebas muestran los siguientes resultados (cadena con símbolos 10000000 como entrada): resultados de la prueba

Александр Иванов
fuente
1
Recomiendo devolver el sparámetro cuando sea nulo o vacío.
MatrixRonny
4

Prueba esto:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}
JoelFan
fuente
2
o tal vez alguna otra clase de caracteres (es decir, alfanumérica \ w), de modo que la función sea compatible con Unicode
Dmitry Ledentsov
@ DmitryLedentsov- La clase de cadena C # se basa en caracteres UTF-16. Clase de cadena "Representa el texto como una secuencia de unidades de código UTF-16".
ToolmakerSteve
4

Si solo le importa que la primera letra esté en mayúscula y no importa el resto de la cadena, puede seleccionar el primer carácter, ponerlo en mayúscula y concatenarlo con el resto de la cadena sin el primer carácter original.

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

Necesitamos convertir el primer carácter ToString () porque lo estamos leyendo como una matriz Char y el tipo Char no tiene el método ToUpper ().

Víctor García
fuente
3

Aquí hay una manera de hacerlo como un método de extensión:

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

Entonces se puede llamar así:

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

Y aquí hay algunas pruebas unitarias para ello:

[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
fuente
1
string.Formates exagerado; simplemente hazlo text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve
3

Ya que estaba trabajando en esto también y estaba buscando ideas, esta es la solución a la que llegué. Utiliza LINQ y podrá poner en mayúscula la primera letra de una cadena, incluso si la primera aparición no es una letra. Aquí está el método de extensión que terminé haciendo.

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

Estoy seguro de que hay una manera de optimizar o limpiar esto un poco.

CAOakley
fuente
3

Encontré algo aquí 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);
}

tal vez esto ayude !!

Mohammed Zameer
fuente
¿Cómo es esto una mejora sobre la respuesta de Equiso 4 años antes?
ToolmakerSteve
3

Compruebe si la cadena no es nula y luego convierta el primer carácter a mayúsculas y el resto a minúsculas:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}
mbadeveloper
fuente
¡Gracias por la pequeña solución en lugar de pocas líneas de código solo por una palabra de cadena!
Imran Faruqi
2

Esto lo hará aunque también se asegurará de que no haya mayúsculas errantes que no estén al principio de la palabra.

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
fuente
2
Necesita una comprobación nula santes de la llamada a ToTitleCase.
Taras Alenin
@ CarlosMuñoz tlhIngan Hol no tiene letras mayúsculas en su guión. :-)
Jonathan Gilbert
2

Parece que hay mucha complejidad aquí cuando todo lo que necesitas es:

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

Puntos dignos de mención:

  1. Es un método de extensión.

  2. Si la entrada es nula, vacía o en blanco, la entrada se devuelve tal cual.

  3. String.IsNullOrWhiteSpace se introdujo con .NET Framework 4. Esto no funcionará con marcos más antiguos.

Stephen Kennedy
fuente
1
No veo cómo esto es una mejora en la respuesta aceptada original de hace cuatro años. De hecho, es inconsistente (inofensivo, pero cuatro años tarde, tengo altos estándares para una nueva respuesta que agrega un beneficio): el único beneficio de usar el IsNullOrWhiteSpacemás nuevo en lugar de IsNullOrEmpty, es si vas a encontrar y cambiar el primer de espacio en blanco . Pero no lo haces, siempre operas s[0]. Por lo tanto, no tiene sentido [semánticamente y rendimiento] para usar IsNullOrWhiteSpace.
ToolmakerSteve
... por qué este uso IsNullOrWhiteSpaceme preocupa, es que un lector descuidado podría pensar "Verificó el espacio en blanco, por lo que el siguiente código realmente encuentra y cambia una letra, incluso si está precedida por un espacio en blanco". Dado que su código no podrá cambiar una "primera" letra precedida por un espacio en blanco, el uso IsNullOrWhiteSpacesolo puede engañar a un lector.
ToolmakerSteve
... Uy, no me refiero a la respuesta aceptada, me refiero a la respuesta de Equiso del mismo período de tiempo.
ToolmakerSteve
1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();
Shailesh
fuente
¿Por qué ToLower () en la cola ?. No hay requisitos para otras letras, excepto la primera.
Carlos Muñoz
Stringes puede ser cualquier cosa de su Uppero Lower.so es una solución genérica para todos cadena.
Shailesh
¿Por qué en Joinlugar de emp.First().ToString().ToUpper() + emp.Substring(1);? Es probable que tenga que ser más defensiva también: output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Además, de acuerdo, @ CarlosMuñoz: no necesitas el ToLower()para la pregunta del OP.
ruffin
@ ruffin -> usar Substring también es un buen estilo de escritura de código, acepto su solución para recortar un código, pero en este caso escribir una ToLower()es una buena práctica de programación. stringpuede ser cualquier cosa En Uppercaso o Lowercaso depende de la entrada del usuario, doy una solución genérica.
Shailesh
@Shailesh - Sin embargo, la pregunta no solicitó que solo la primera letra fuera mayúscula. Pidió que se cambiara la primera letra para que fuera mayúscula. Sin más aclaraciones del autor, la suposición más natural es que el resto de la cadena no se modifique. Dado que está respondiendo tres años después , suponga que la respuesta aceptada hace lo que solicitó el solicitante. Solo dé una respuesta diferente si hay alguna razón técnica para hacerlo de manera diferente.
ToolmakerSteve
1

Quería proporcionar una respuesta de "RENDIMIENTO MÁXIMO". En mi opinión, una respuesta de "RENDIMIENTO MÁXIMO" capta todos los escenarios y proporciona la respuesta a la pregunta que explica esos escenarios. Entonces, aquí está mi respuesta. Con estos motivos:

  1. IsNullOrWhiteSpace representa cadenas que son solo espacios o nulas / vacías.
  2. .Trim () elimina los espacios en blanco de la parte frontal y posterior de la cadena.
  3. .First () toma el primer carácter de un número (o cadena) numerable.
  4. Deberíamos verificar si es una letra que puede / debe estar en mayúscula.
  5. Luego agregamos el resto de la cadena, solo si la longitud indica que deberíamos.
  6. Según las mejores prácticas de .Net, debemos proporcionar una cultura en System.Globalization.CultureInfo.
  7. Proporcionarlos como parámetros opcionales hace que este método sea totalmente reutilizable, sin tener que escribir la cultura elegida cada vez.

    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
fuente
2
Si bien esto cubre la mayoría de los casos, ¿no sería lento considerando la cantidad de cadenas que se crean con cada operación? Aquí hay una tonelada de asignación de cadenas. Preferiblemente se asignaría una vez, y solo una vez.
Douglas Gaskell
1

Recientemente tuve un requisito similar y recordé que la función LINQ Select () proporciona un í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 necesito eso muy a menudo, hice un método de extensión para el tipo de cadena:

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

Tenga en cuenta que solo la primera letra se convierte a mayúscula; no se tocan todos los caracteres restantes. Si necesita que los otros caracteres estén en minúsculas, también puede llamar a Char.ToLower (currentChar) para index> 0 o llamar a ToLower () en toda la cadena en primer lugar.

En cuanto al rendimiento, comparé el código con la solución de Darren. En mi máquina, el código de Darren es aproximadamente 2 veces más rápido, lo cual no es sorprendente, ya que está editando directamente solo la primera letra dentro de una matriz de caracteres. Así que le sugiero que tome el código de Darren si necesita la solución más rápida disponible. Si desea integrar también otras manipulaciones de cadenas, puede ser conveniente tener el poder expresivo de una función lambda tocando los caracteres de la cadena de entrada, puede extender fácilmente esta función, así que dejo esta solución aquí.

Grimm
fuente
Me preguntaba cómo resolvería este problema, resolví mi propia solución, luego volví a publicarla solo para descubrir que había encontrado exactamente la misma solución que ya tenía. +1 para ti!
BlueFuzzyThing
Muchas gracias.
Grimm
1

Creo que el siguiente método es la mejor solución.

    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

árbitro

D.JCode
fuente
1

Como esta pregunta se trata de maximizar el rendimiento , adopté la versión de Darren para usar Spans, que reduce la basura y mejora la velocidad en aproximadamente un 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);
        }

Actuación

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

}

Editar: Hubo un typeo, en lugar de s [0], fue un [0] - esto da como resultado el encapsulado del mismo valor vacío al Span asignado a.

Marcell Toth
fuente
0

Esto pone en mayúscula esta primera letra y cada letra después de un espacio y en minúsculas cualquier otra 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
fuente
1
O si no desea escribir muros de código: CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); hace lo mismo
Chev
Sí ... no sabía sobre eso :) Y debido a mi enorme cantidad de código, las respuestas de todos los demás aparecieron mientras todavía estaba escribiendo.
thattolleyguy
UPVOTED: 1) Una ligera diferencia entre esta respuesta y ToTitleCase, es que esta respuesta obliga a que todas las mayúsculas se conviertan en TitleCase, mientras que ToTitleCase deja esas palabras solas (se supone que pueden ser siglas). Esto podría o no ser lo que se desea. Una ventaja de tener un código de ejemplo como este es que se puede modificar como se desee. 2) esto no manejará el espacio en blanco que no sea '' correctamente. debe reemplazar la prueba en blanco con la prueba de espacio en blanco.
ToolmakerSteve
0

Utiliza el siguiente código:

string  strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();
Prashant Banavali
fuente
Ni siquiera vale la pena que mi representante rechace esta respuesta agregada años después, que obviamente es equivalente a respuestas ya existentes. Si va a agregar una nueva respuesta a una pregunta con muchas respuestas, explique qué cree que es superior sobre su respuesta, o bajo qué circunstancias su respuesta sería más útil que otras respuestas. Se específico.
ToolmakerSteve
0

Parece que ninguna de las soluciones dadas aquí tratará con un espacio en blanco antes de la cadena.

Solo agrego esto como un pensamiento:

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

Debe manejar this won't work on other answers(esa oración tiene un espacio al principio), y si no le gusta el recorte de espacio, simplemente pase un falsesegundo parámetro (o cambie el valor predeterminado a false, y pase truesi desea tratar con espacio)

Noctis
fuente
0

La forma más fácil de capitalizar la primera letra es:

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
fuente
1
Esta respuesta es esencialmente idéntica a las respuestas dadas años antes. No agrega nada a la discusión.
ToolmakerSteve
También es incorrecto, al igual que el comentario en el otro, esto convierte cada primera letra en todas las palabras en mayúscula, no en Casa Roja en lugar de Casa Roja.
DeadlyChambers
0

La siguiente función es correcta en todos los sentidos:

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

Encontré eso aquí


fuente
¿Por qué? ¿Por qué agregar otra respuesta cuando ya hay tantas respuestas que parecen similares? ¿Qué hay de malo con todas las respuestas existentes, que te impulsaron a agregar otra?
ToolmakerSteve
Porque este answare es correcto en todos los sentidos. Tómalo con calma.
Lo siento; Era innecesariamente duro. Me atendré a los hechos: 1) Esto es esencialmente lo mismo que la respuesta de ese tolley siete años antes. 2) Esto tiene el mismo defecto que la respuesta: no maneja espacios en blanco que no sean caracteres en blanco. 3) Esto responde a una pregunta ligeramente diferente a la que estaba haciendo OP. Use una respuesta como esta si desea que todas las palabras tengan la primera letra en mayúscula. 4) Por lo general, la forma más sencilla de lograrlo es usar TitleInfo.ToTitleCase. (Por otro lado, una ventaja de la muestra de código es que se puede personalizar como se desee)
ToolmakerSteve
Corregirme a mí mismo: esto es diferente al enfoque de thattolleyguy: deja letras intactas que no son la primera letra de la palabra. En cambio, es un duplicado de la respuesta de zamoldar . Favorablemente, felicitaciones a Darian por dar el enlace a la fuente : parece zamoldar plagiado sin dar crédito. Debido a que proporcioné ese enlace de fuente y, por lo tanto , mejoré la discusión , estoy votando esta respuesta, a pesar de mis críticas.
ToolmakerSteve
1
Darian, dos mejoras que podrían hacerse: 1) usar en char.IsWhiteSpace( array[ i -1 ] )lugar de.. == ' ' , para manejar todo el espacio en blanco. 2) elimine los dos lugares que lo hacen if (char.isLower(..)), no sirven para nada. ToUppersimplemente no hace nada si un personaje no es minúscula.
ToolmakerSteve
0

Ampliando la pregunta de Carlos anterior, si desea capitalizar varias oraciones, puede usar 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
fuente
0

Posible solución para resolver su 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
fuente