Czy istnieje łatwy sposób na zapisanie pierwszej litery ciągu wielką literą i zmniejszenie pozostałej części? Czy istnieje metoda wbudowana, czy też muszę stworzyć własną?
Czy istnieje łatwy sposób na zapisanie pierwszej litery ciągu wielką literą i zmniejszenie pozostałej części? Czy istnieje metoda wbudowana, czy też muszę stworzyć własną?
Odpowiedzi:
TextInfo.ToTitleCase()
zamienia na wielką literę pierwszy znak w każdym tokenie ciągu.
Jeśli nie ma potrzeby zachowywania dużych liter akronimów, należy dołączyć ToLower()
.
string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"
Jeśli CurrentCulture jest niedostępna, użyj:
string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());
Aby uzyskać szczegółowy opis, zobacz łącze MSDN .
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");
sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case
CurrentCulture
, jak możemy być pewni, że nie ma kultury, która traktuje to inaczej?
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);
Powyższy kod nie zadziała .....
więc umieść poniższy kod, konwertując na niższy, a następnie zastosuj funkcję
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());
Istnieją przypadki, które CultureInfo.CurrentCulture.TextInfo.ToTitleCase
nie mogą sobie poradzić, na przykład: apostrof '
.
string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo
Regex mogą być również wykorzystywane \b[a-zA-Z]
do identyfikacji charakteru wyjściowej słowem po granicy słowa \b
, to musimy po prostu zastąpić meczu przez jego górną część obudowy równoważności dzięki Regex.Replace(string input,string pattern,MatchEvaluator evaluator)
metodzie:
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
Wyrażenie regularne można w razie potrzeby dostroić, na przykład, jeśli chcemy obsłużyć przypadki MacDonald
i, McFry
wyrażenie regularne staje się:(?<=\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
Jeśli musimy obsłużyć więcej prefiksów musimy tylko zmodyfikować grupę (?:mc|mac)
, na przykład, aby dodać french przedrostki du, de
: (?:mc|mac|du|de)
.
Wreszcie, możemy zdać sobie sprawę, że to wyrażenie regularne będzie również pasowało do przypadku MacDonald'S
ostatniego, 's
więc musimy zająć się nim w wyrażeniu regularnym z negatywnym spojrzeniem w tył (?<!'s\b)
. Na koniec mamy:
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]+$|
tak jest \b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)
. Będzie składać się z wszystkich końcowych słów nazwy mającej nieścisły format liczb rzymskich ( ivxlcdm
). Możesz jednak mieć niepożądane wyniki, na przykład „Li” zmieni się w „LI”
Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())
Mc i Mac to powszechne przedrostki nazwisk w całych Stanach Zjednoczonych, ale są też inne. TextInfo.ToTitleCase nie obsługuje takich przypadków i nie powinien być używany do tego celu. Oto jak to robię:
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 () powinno działać dla Ciebie.
Najbardziej bezpośrednią opcją będzie użycie funkcji ToTitleCase, która jest dostępna w .NET, która powinna zajmować się nazwą przez większość czasu. Jak zauważył Edg , jest kilka nazw, dla których to nie zadziała, ale są one dość rzadkie, więc jeśli nie celujesz w kulturę, w której takie nazwy są powszechne, nie jest konieczne coś, o co musisz się zbytnio martwić.
Jeśli jednak nie pracujesz z językiem .NET, to zależy od tego, jak wygląda dane wejściowe - jeśli masz dwa oddzielne pola na imię i nazwisko, możesz po prostu zamienić pierwszą literę na wielką, a resztę za pomocą podciągi.
firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();
Jeśli jednak otrzymałeś kilka nazwisk jako część tego samego ciągu, musisz wiedzieć, w jaki sposób otrzymujesz informacje i odpowiednio je podzielić . Więc jeśli otrzymujesz imię takie jak „John Doe”, podziel ciąg na podstawie znaku spacji. Jeśli jest w formacie takim jak „Kowalski, Jan”, będziesz musiał podzielić go na podstawie przecinka. Jednak po rozdzieleniu wystarczy zastosować kod pokazany wcześniej.
Używam własnej metody, aby to naprawić:
Na przykład wyrażenie: „witaj świecie. Witaj, to jest świat przepełnienia stosów”. będzie „Hello World. Hello This Is The Stackoverflow World.”. Regex \ b (początek słowa) \ w (pierwszy znak słowa) załatwi sprawę.
/// <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;
}
Sugestie dotyczące użycia ToTitleCase nie będą działać w przypadku ciągów zawierających wielkie litery. Więc będziesz musiał wywołać ToUpper na pierwszym znaku i ToLower na pozostałych.
Ta klasa załatwia sprawę. Możesz dodać nowe przedrostki do statycznej tablicy ciągów _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();
}
}
Jeśli używasz vS2k8, możesz użyć metody rozszerzającej, aby dodać ją do klasy 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)
jest bardziej czytelny IMHO.
input.FirstLetterToUpper()
jest z pewnością bardziej czytelne w porównaniu z Char.ToUpper(input[0]) + input.Substring(1)
, ale mniej przejrzyste
Aby obejść niektóre problemy / problemy, które zostały wyróżnione, sugerowałbym najpierw przekonwertowanie ciągu znaków na małe litery, a następnie wywołanie metody ToTitleCase. Następnie możesz użyć IndexOf („Mc”) lub IndexOf („O \”), aby określić szczególne przypadki, które wymagają bardziej szczegółowej uwagi.
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);
}
Lubię ten sposób:
using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());
Zaczerpnięte z tego artykułu 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;
}
Jak wskazał Edg, będziesz potrzebować bardziej złożonego algorytmu do obsługi nazw specjalnych (prawdopodobnie dlatego wiele miejsc wymusza pisanie wielkich liter).
Coś takiego jak ten nieprzetestowany C # powinno obsłużyć prosty przypadek, o który prosiłeś:
public string SentenceCase(string input)
{
return input(0, 1).ToUpper + input.Substring(1).ToLower;
}