Existe uma maneira fácil de colocar em maiúscula a primeira letra de uma string e diminuir o restante? Existe um método embutido ou preciso criar o meu?
Existe uma maneira fácil de colocar em maiúscula a primeira letra de uma string e diminuir o restante? Existe um método embutido ou preciso criar o meu?
Respostas:
TextInfo.ToTitleCase()
coloca em maiúscula o primeiro caractere em cada token de uma string.
Se não houver necessidade de manter a sigla Maiúsculas, inclua ToLower()
.
string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"
Se CurrentCulture estiver indisponível, use:
string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");
sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case
CurrentCulture
, como podemos ter certeza de que não há cultura que lide com isso de maneira diferente?
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);
O código acima não funcionará .....
então coloque o código abaixo convertendo para lower e aplique a função
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());
Existem alguns casos que CultureInfo.CurrentCulture.TextInfo.ToTitleCase
não conseguem lidar, por exemplo: o apóstrofo '
.
string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo
Um regex também pode ser usado \b[a-zA-Z]
para identificar o caractere inicial de uma palavra após o limite de uma palavra \b
; então, basta substituir a correspondência por sua equivalência em maiúsculas, graças ao 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
A regex pode ser ajustado, se necessário, por exemplo, se quisermos lidar com os MacDonald
e McFry
casos, o regex se torna:(?<=\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
Se precisamos lidar com mais prefixos só precisamos modificar o grupo (?:mc|mac)
, por exemplo, para adicionar prefixos francês du, de
: (?:mc|mac|du|de)
.
Finalmente, podemos perceber que esse regex também corresponderá ao caso MacDonald'S
anterior, 's
por isso precisamos lidar com ele no regex com um olhar negativo para trás (?<!'s\b)
. No final, temos:
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]+$|
assim é \b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)
. Ele fará maiúsculas todas as palavras finais de um nome que tenha um formato de número romano não estrito ( ivxlcdm
). No entanto, você pode ter resultados indesejados, por exemplo, 'Li' se tornará 'LI'
Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())
Mc e Mac são prefixos de sobrenome comuns nos EUA, e existem outros. O TextInfo.ToTitleCase não trata desses casos e não deve ser usado para essa finalidade. Aqui está como eu estou fazendo isso:
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 () deve funcionar para você.
A opção mais direta será usar a função ToTitleCase disponível no .NET, que deve cuidar do nome na maioria das vezes. Como o edg apontou, existem alguns nomes para os quais ele não funcionará, mas esses são razoavelmente raros; portanto, a menos que você esteja direcionando uma cultura em que esses nomes sejam comuns, não é necessário algo com que você tenha que se preocupar muito.
No entanto, se você não estiver trabalhando com um idioma .NET, isso dependerá da aparência da entrada - se você tiver dois campos separados para o primeiro nome e o sobrenome, poderá colocar em maiúscula a primeira letra e diminuir o restante usando substrings.
firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();
No entanto, se você receber vários nomes como parte da mesma sequência, precisará saber como está obtendo as informações e dividi-las de acordo. Portanto, se você estiver recebendo um nome como "John Doe", divida a string com base no caractere de espaço. Se estiver em um formato como "Doe, John", será necessário dividi-lo com base na vírgula. No entanto, depois de dividir, basta aplicar o código mostrado anteriormente.
Eu uso meu próprio método para corrigir isso:
Por exemplo, a frase: "olá mundo. Olá, este é o mundo stackoverflow". será "Olá, mundo. Olá, este é o mundo do Stackoverflow". Regex \ b (início de uma palavra) \ w (primeiro caractere da palavra) fará o truque.
/// <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;
}
As sugestões para usar o ToTitleCase não funcionarão para seqüências de caracteres todas em maiúsculas. Então você precisará chamar o ToUpper no primeiro caractere e o ToLower nos caracteres restantes.
Esta classe faz o truque. Você pode adicionar novos prefixos à matriz de cadeias 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();
}
}
Se você estiver usando o vS2k8, poderá usar um método de extensão para adicioná-lo à classe 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)
é IMHO mais legível.
input.FirstLetterToUpper()
é certamente mais legível vs. Char.ToUpper(input[0]) + input.Substring(1)
, mas menos transparente #
Para contornar alguns dos problemas / problemas que foram destacados, sugiro converter a string para minúscula primeiro e depois chamar o método ToTitleCase. Você pode usar IndexOf ("Mc") ou IndexOf ("O \ '") para determinar casos especiais que precisam de atenção mais 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);
}
Eu gosto desta maneira:
using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());
Retirado deste artigo do MSDN .
Espero que isso ajude você.
String fName = "firstname";
String lName = "lastname";
String capitalizedFName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(fName);
String capitalizedLName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(lName);
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 edg indicado, você precisará de um algoritmo mais complexo para lidar com nomes especiais (é provavelmente por isso que muitos lugares forçam tudo a maiúsculas).
Algo como este c # não testado deve lidar com o caso simples que você solicitou:
public string SentenceCase(string input)
{
return input(0, 1).ToUpper + input.Substring(1).ToLower;
}