¿Hay alguna manera fácil de poner en mayúscula la primera letra de una cadena y bajar el resto? ¿Existe un método incorporado o necesito hacer el mío?
¿Hay alguna manera fácil de poner en mayúscula la primera letra de una cadena y bajar el resto? ¿Existe un método incorporado o necesito hacer el mío?
Respuestas:
TextInfo.ToTitleCase()
capitaliza el primer carácter en cada ficha de una cadena.
Si no es necesario mantener las siglas en mayúsculas, entonces debe incluir ToLower()
.
string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"
Si CurrentCulture no está disponible, use:
string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());
Consulte el enlace de MSDN para obtener una descripción detallada.
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");
sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case
CurrentCulture
, ¿cómo podemos estar seguros de que no hay una cultura que maneje esto de manera diferente?
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);
El código anterior no funcionará .....
así que pon el siguiente código convirtiendo a inferior y luego aplica la función
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());
Hay algunos casos que CultureInfo.CurrentCulture.TextInfo.ToTitleCase
no pueden manejar, por ejemplo: el apóstrofe '
.
string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo
Una expresión regular también se puede usar \b[a-zA-Z]
para identificar el carácter inicial de una palabra después del límite de una palabra \b
, entonces solo necesitamos reemplazar la coincidencia por su equivalencia en mayúsculas gracias al Regex.Replace(string input,string pattern,MatchEvaluator evaluator)
método:
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
La expresión regular se puede ajustar si es necesario, por ejemplo, si queremos manejar los casos MacDonald
y McFry
la expresión regular se convierte en:(?<=\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
Si tenemos que manejar más prefijos sólo tenemos que modificar el grupo (?:mc|mac)
, por ejemplo, para añadir prefijos francés du, de
: (?:mc|mac|du|de)
.
Finalmente, podemos darnos cuenta de que esta expresión regular también coincidirá con el caso MacDonald'S
para el último, 's
por lo que debemos manejarla en la expresión regular con una mirada negativa hacia atrás (?<!'s\b)
. Al final tenemos:
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
\b[ivxlcdm]+$|
así es \b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)
. Hará mayúsculas todas las palabras finales de un nombre que tenga un formato de número romano no estricto ( ivxlcdm
). Sin embargo, puede tener algunos resultados no deseados, por ejemplo, 'Li' se convertirá en 'LI'
Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())
Mc y Mac son prefijos de apellidos comunes en todo EE. UU., Y hay otros. TextInfo.ToTitleCase no maneja esos casos y no debe usarse para este propósito. Así es como lo estoy haciendo:
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;
}
ToTitleCase () debería funcionar para usted.
La opción más directa será utilizar la función ToTitleCase que está disponible en .NET, que debería ocuparse del nombre la mayor parte del tiempo. Como señaló Edg , hay algunos nombres para los que no funcionará, pero estos son bastante raros, por lo que, a menos que se dirija a una cultura donde tales nombres son comunes, no es necesario algo de lo que deba preocuparse demasiado.
Sin embargo, si no está trabajando con un lenguaje .NET, entonces depende de cómo se vea la entrada; si tiene dos campos separados para el nombre y el apellido, entonces puede poner en mayúscula la primera letra más abajo usando el resto. subcadenas.
firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();
Sin embargo, si se le proporcionan varios nombres como parte de la misma cadena, entonces necesita saber cómo está obteniendo la información y dividirla en consecuencia. Entonces, si obtiene un nombre como "John Doe", puede dividir la cadena en función del carácter de espacio. Si está en un formato como "Doe, John", deberá dividirlo según la coma. Sin embargo, una vez que lo haya dividido, simplemente aplique el código que se mostró anteriormente.
Yo uso mi propio método para arreglar esto:
Por ejemplo, la frase: "hola mundo. Hola, este es el mundo de stackoverflow". será "Hola mundo. Hola, este es el mundo de Stackoverflow". Regex \ b (comienzo de una palabra) \ w (primer personaje de la palabra) hará el truco.
/// <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;
}
Las sugerencias para usar ToTitleCase no funcionarán para cadenas que están en mayúsculas. Entonces tendrás que llamar a ToUpper en el primer personaje y a ToLower en los personajes restantes.
Esta clase hace el truco. Puede agregar nuevos prefijos a la matriz de cadenas estáticas _prefixes .
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();
}
}
Si usa vS2k8, puede usar un método de extensión para agregarlo a la clase String:
public static string FirstLetterToUpper(this String input)
{
return input = input.Substring(0, 1).ToUpper() +
input.Substring(1, input.Length - 1);
}
Char.ToUpper(input[0]) + input.Substring(1)
es más legible en mi humilde opinión.
input.FirstLetterToUpper()
es ciertamente más legible frente Char.ToUpper(input[0]) + input.Substring(1)
, pero menos transparente
Para resolver algunos de los problemas / problemas que se han destacado, sugeriría convertir primero la cadena a minúscula y luego llamar al método ToTitleCase. Luego puede usar IndexOf ("Mc") o IndexOf ("O \ '") para determinar casos especiales que requieren atención más específica.
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);
}
Me gusta de esta manera:
using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());
Retirado de este artículo de MSDN .
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;
}
Como se indica en edg, necesitará un algoritmo más complejo para manejar nombres especiales (esta es probablemente la razón por la cual muchos lugares fuerzan todo a mayúsculas).
Algo como esto no probado c # debería manejar el caso simple que solicitó:
public string SentenceCase(string input)
{
return input(0, 1).ToUpper + input.Substring(1).ToLower;
}