Gibt es eine einfache Möglichkeit, den ersten Buchstaben einer Zeichenfolge groß zu schreiben und den Rest zu senken? Gibt es eine eingebaute Methode oder muss ich meine eigene erstellen?
Gibt es eine einfache Möglichkeit, den ersten Buchstaben einer Zeichenfolge groß zu schreiben und den Rest zu senken? Gibt es eine eingebaute Methode oder muss ich meine eigene erstellen?
Antworten:
TextInfo.ToTitleCase()
Großschreibung des ersten Zeichens in jedem Token einer Zeichenfolge.
Wenn es nicht erforderlich ist, das Akronym Uppercasing beizubehalten, sollten Sie einschließen ToLower()
.
string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"
Wenn CurrentCulture nicht verfügbar ist, verwenden Sie:
string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());
Eine detaillierte Beschreibung finden Sie im MSDN-Link .
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");
sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case
CurrentCulture
, wie können wir sicher sein , dass es keine Kultur, die dies anders behandelt?
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);
Der obige Code funktioniert nicht .....
Geben Sie also den folgenden Code ein, indem Sie ihn in einen niedrigeren Wert konvertieren, und wenden Sie dann die Funktion an
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());
Es gibt einige Fälle, CultureInfo.CurrentCulture.TextInfo.ToTitleCase
die nicht behandelt werden können, zum Beispiel den Apostroph '
.
string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo
Ein regulärer Ausdruck kann auch verwendet werden \b[a-zA-Z]
, um das Startzeichen eines Wortes nach einer Wortgrenze zu identifizieren. \b
Dann müssen wir die Übereinstimmung dank der folgenden Regex.Replace(string input,string pattern,MatchEvaluator evaluator)
Methode nur durch ihre Großbuchstabenäquivalenz ersetzen :
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
Der Regex kann bei Bedarf angepasst werden, zum Beispiel, wenn wir die MacDonald
und McFry
Fälle behandeln möchten, aus denen der Regex wird:(?<=\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
Wenn wir mehr Präfixe verarbeiten müssen, müssen wir nur die Gruppe ändern (?:mc|mac)
, um beispielsweise französische Präfixe hinzuzufügen du, de
: (?:mc|mac|du|de)
.
Schließlich können wir erkennen, dass dieser Regex auch mit dem MacDonald'S
letzten übereinstimmt, 's
sodass wir ihn im Regex mit einem negativen Blick nach hinten behandeln müssen (?<!'s\b)
. Am Ende haben wir:
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]+$|
Sie haben es also \b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)
. Alle Endwörter eines Namens mit einem nicht strengen römischen Zahlenformat ( ivxlcdm
) werden in Großbuchstaben geschrieben . Sie können jedoch einige unerwünschte Ergebnisse haben, zum Beispiel wird 'Li' zu 'LI'
Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())
Mc und Mac sind in den USA gebräuchliche Familiennamenpräfixe, und es gibt andere. TextInfo.ToTitleCase behandelt diese Fälle nicht und sollte nicht für diesen Zweck verwendet werden. So mache ich das:
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 () sollte für Sie funktionieren.
Die direkteste Option ist die Verwendung der in .NET verfügbaren ToTitleCase- Funktion, die sich die meiste Zeit um den Namen kümmern sollte. Wie edg hervorhob , gibt es einige Namen, für die es nicht funktioniert, aber diese sind ziemlich selten. Wenn Sie also nicht auf eine Kultur abzielen, in der solche Namen häufig vorkommen, ist es nicht notwendig, dass Sie sich zu viele Sorgen machen müssen.
Wenn Sie jedoch nicht mit einer .NET-Sprache arbeiten, hängt dies davon ab, wie die Eingabe aussieht. Wenn Sie zwei separate Felder für den Vor- und Nachnamen haben, können Sie einfach den ersten Buchstaben groß schreiben und den Rest mit verwenden Teilzeichenfolgen.
firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();
Wenn Sie jedoch mehrere Namen als Teil derselben Zeichenfolge erhalten, müssen Sie wissen, wie Sie die Informationen erhalten, und sie entsprechend aufteilen . Wenn Sie also einen Namen wie "John Doe" erhalten, teilen Sie die Zeichenfolge basierend auf dem Leerzeichen. Wenn es in einem Format wie "Doe, John" vorliegt, müssen Sie es anhand des Kommas aufteilen. Sobald Sie es jedoch aufgeteilt haben, wenden Sie einfach den zuvor gezeigten Code an.
CultureInfo.CurrentCulture.TextInfo.ToTitleCase ("mein Name");
gibt ~ Mein Name zurück
Das Problem besteht jedoch weiterhin bei Namen wie McFly, wie bereits erwähnt.
Ich benutze meine eigene Methode, um dies zu beheben:
Zum Beispiel der Satz: "Hallo Welt. Hallo, das ist die Stackoverflow-Welt." wird "Hallo Welt. Hallo, das ist die Stackoverflow-Welt." sein. Regex \ b (Wortanfang) \ w (erster Charakter des Wortes) macht den Trick.
/// <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;
}
Die Vorschläge zur Verwendung von ToTitleCase funktionieren nicht für Zeichenfolgen, die alle in Großbuchstaben geschrieben sind. Sie müssen also ToUpper für das erste Zeichen und ToLower für die verbleibenden Zeichen aufrufen.
Diese Klasse macht den Trick. Sie können dem statischen String-Array _prefixes neue Präfixe hinzufügen .
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();
}
}
Wenn Sie vS2k8 verwenden, können Sie es mithilfe einer Erweiterungsmethode zur String-Klasse hinzufügen:
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)
ist meiner Meinung nach besser lesbar.
input.FirstLetterToUpper()
ist sicherlich mehr lesbar gegen Char.ToUpper(input[0]) + input.Substring(1)
, aber weniger transparent
Um einige der Probleme zu umgehen, die hervorgehoben wurden, würde ich vorschlagen, die Zeichenfolge zuerst in Kleinbuchstaben umzuwandeln und dann die ToTitleCase-Methode aufzurufen. Sie können dann IndexOf ("Mc") oder IndexOf ("O \ '") verwenden, um Sonderfälle zu ermitteln, die besondere Aufmerksamkeit erfordern.
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);
}
Ich mag diesen Weg:
using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());
Aus diesem MSDN-Artikel entnommen .
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;
}
Wie von edg angegeben, benötigen Sie einen komplexeren Algorithmus, um spezielle Namen zu verarbeiten (dies ist wahrscheinlich der Grund, warum viele Stellen alles in Großbuchstaben zwingen).
So etwas wie dieses ungetestete c # sollte den von Ihnen angeforderten einfachen Fall behandeln:
public string SentenceCase(string input)
{
return input(0, 1).ToUpper + input.Substring(1).ToLower;
}