C'è un modo semplice per scrivere in maiuscolo la prima lettera di una stringa e abbassarne il resto? Esiste un metodo integrato o devo crearne uno mio?
C'è un modo semplice per scrivere in maiuscolo la prima lettera di una stringa e abbassarne il resto? Esiste un metodo integrato o devo crearne uno mio?
Risposte:
TextInfo.ToTitleCase()
mette in maiuscolo il primo carattere in ogni token di una stringa.
Se non è necessario mantenere Acronimo in maiuscolo, è necessario includere ToLower()
.
string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"
Se CurrentCulture non è disponibile, utilizzare:
string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());
Vedere il collegamento MSDN per una descrizione dettagliata.
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");
sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case
CurrentCulture
, come possiamo essere sicuri che non esiste cultura che la gestisca diversamente?
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);
Il codice sopra non funzionerà .....
quindi inserisci il codice seguente convertendolo in basso quindi applica la funzione
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());
Ci sono alcuni casi che CultureInfo.CurrentCulture.TextInfo.ToTitleCase
non possono essere gestiti, ad esempio: l'apostrofo '
.
string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo
Un regex può anche essere usato \b[a-zA-Z]
per identificare il carattere iniziale di una parola dopo un confine di parola \b
, quindi dobbiamo semplicemente sostituire la corrispondenza con la sua equivalenza maiuscola grazie al Regex.Replace(string input,string pattern,MatchEvaluator evaluator)
metodo:
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
Il regex può essere regolato se necessario, ad esempio, se vogliamo gestire i casi MacDonald
e McFry
il regex diventa:(?<=\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 abbiamo bisogno di gestire più prefissi abbiamo solo bisogno di modificare il gruppo (?:mc|mac)
, ad esempio per aggiungere prefissi francesi du, de
: (?:mc|mac|du|de)
.
Infine, possiamo renderci conto che questa regex corrisponderà anche al caso MacDonald'S
dell'ultimo, 's
quindi dobbiamo gestirla nella regex con uno sguardo negativo dietro (?<!'s\b)
. Alla fine abbiamo:
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]+$|
così avete \b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)
. Rende maiuscole tutte le parole finali di un nome che ha un formato numerico romano non rigoroso ( ivxlcdm
). Potresti avere comunque dei risultati indesiderati, ad esempio 'Li' diventerà 'LI'
Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())
Mc e Mac sono prefissi dei cognomi comuni negli Stati Uniti, e ce ne sono altri. TextInfo.ToTitleCase non gestisce questi casi e non dovrebbe essere utilizzato per questo scopo. Ecco come lo sto facendo:
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 () dovrebbe funzionare per te.
L'opzione più diretta sarà quella di utilizzare la funzione ToTitleCase disponibile in .NET che dovrebbe occuparsi del nome per la maggior parte del tempo. Come ha sottolineato edg , ci sono alcuni nomi per cui non funzionerà, ma questi sono abbastanza rari, quindi a meno che tu non stia prendendo di mira una cultura in cui tali nomi sono comuni, non è necessario qualcosa di cui devi preoccuparti troppo.
Tuttavia, se non stai lavorando con una lingua .NET, dipende dall'aspetto dell'input: se hai due campi separati per il nome e il cognome, puoi solo mettere in maiuscolo la prima lettera per abbassare il resto usando sottostringhe.
firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();
Tuttavia, se ti vengono forniti più nomi come parte della stessa stringa, devi sapere come stai ottenendo le informazioni e dividerle di conseguenza. Quindi, se stai ottenendo un nome come "John Doe", dividi la stringa in base al carattere dello spazio. Se è in un formato come "Doe, John" dovrai dividerlo in base alla virgola. Tuttavia, una volta diviso, basta applicare il codice mostrato in precedenza.
CultureInfo.CurrentCulture.TextInfo.ToTitleCase ("il mio nome");
restituisce ~ My Name
Ma il problema esiste ancora con nomi come McFly, come affermato in precedenza.
Uso il mio metodo per risolvere il problema:
Ad esempio la frase: "ciao mondo. Ciao questo è il mondo dello stackoverflow". sarà "Hello World. Hello This Is The Stackoverflow World". Regex \ b (inizio di una parola) \ w (primo carattere della parola) farà il trucco.
/// <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;
}
I suggerimenti per usare ToTitleCase non funzioneranno con stringhe tutte in maiuscolo. Quindi dovrai chiamare ToUpper sul primo personaggio e ToLower sui personaggi rimanenti.
Questa classe fa il trucco. È possibile aggiungere nuovi prefissi all'array di stringhe statiche _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 si utilizza vS2k8, è possibile utilizzare un metodo di estensione per aggiungerlo alla 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)
è più leggibile IMHO.
input.FirstLetterToUpper()
è sicuramente più leggibile vs. Char.ToUpper(input[0]) + input.Substring(1)
, ma meno trasparente
Per ovviare ad alcuni dei problemi / problemi che sono stati ben evidenziati, suggerirei prima di convertire la stringa in minuscolo e poi di chiamare il metodo ToTitleCase. È quindi possibile utilizzare IndexOf ("Mc") o IndexOf ("O \ '") per determinare casi speciali che richiedono un'attenzione più specifica.
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);
}
Mi piace così:
using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());
Tratto da questo articolo 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;
}
Come indicato da edg, avrai bisogno di un algoritmo più complesso per gestire nomi speciali (questo è probabilmente il motivo per cui molti posti impongono tutto in maiuscolo).
Qualcosa di simile a questo c # non testato dovrebbe gestire il semplice caso richiesto:
public string SentenceCase(string input)
{
return input(0, 1).ToUpper + input.Substring(1).ToLower;
}