Как отформатировать строку в Название дела?


Вот простой статический метод сделать это на C#:
public static string ToTitleCaseInvariant(string targetString)
{
return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(targetString);
}
Если это не самая длинная квалификация ... Throw.In.Todays.News.While.Youre.At.It(...);
Однако имейте в виду, что если вся начальная строка состоит из прописных букв, вам нужно сначала вызвать String.ToLower, поскольку ToTitleCase не работает со всеми строками в верхнем регистре.
Насколько это инвариантно, если вы используете текущую культуру?
Без использования готовой функции суперпростой низкоуровневый алгоритм преобразования строки в регистр заголовка:
convert first character to uppercase.
for each character in string,
if the previous character is whitespace,
convert character to uppercase.
Это предполагает, что «преобразование символа в верхний регистр» будет делать это правильно независимо от того, чувствителен ли символ к регистру (например, '+').
Это не относится к заглавным буквам, где маленькие слова (артикли и предлоги) не должны начинаться с заглавной буквы.
Если используемый вами язык имеет поддерживаемый метод / функцию, просто используйте его (как в методе C# ToTitleCase).
Если это не так, вам нужно сделать что-то вроде следующего:
1 Чтобы использовать его, скажем, в C - используйте коды ascii, чтобы найти целое значение символа и вычесть из него 32.
В коде потребуется гораздо больше проверок ошибок (обеспечение допустимых букв и т. д.), А функция «Заглавные буквы» должна будет наложить на буквы своего рода «схему заглавных букв», чтобы проверять слова, в которых нет необходимости. быть capatilised ('и', 'но' и т. д. Здесь - хорошая схема)
Полностью не работает с кодовыми таблицами, например, Немецкий, где умляуты (äöü) имеют прописные буквы, которые не соответствуют этому шаблону.
Вот решение Perl http://daringfireball.net/2008/05/title_case
Вот решение Ruby http://frankschmitt.org/projects/title-case
Вот однострочное решение Ruby: http://snippets.dzone.com/posts/show/4702
'some string here'.gsub(/\b\w/){$&.upcase}
В однострочном выражении первый символ каждого слова заменяется регулярным выражением на его версию в верхнем регистре.
Я бы опасался автоматического преобразования всех слов с пробелами в начале в сценариях, в которых я рискую вызвать ярость придирчивых.
Я бы хотя бы подумал о создании словаря для исключительных случаев, таких как статьи и союзы. Вот:
"Beauty and the Beast"
А когда дело доходит до имен собственных, все становится еще уродливее.
To capatilise it in, say, C - use the ascii codes (http://www.asciitable.com/) to find the integer value of the char and subtract 32 from it.
Это плохое решение, если вы когда-нибудь планируете принимать символы за пределами a-z и A-Z.
Например: ASCII 134: å, ASCII 143: Å.
.
Используя арифметику, вы получите: ASCII 102: f
Используйте вызовы библиотеки, не думайте, что вы можете использовать целочисленную арифметику для своих персонажей, чтобы получить что-то полезное. Юникод - это сложный.
С Perl вы можете сделать это:
my $tc_string = join ' ', map { ucfirst($\_) } split /\s+/, $string;
Это не относится к заглавным буквам, где маленькие слова (артикли и предлоги) не должны начинаться с заглавной буквы.
В Perl:
$string =~ s/(\w+)/\u\L/g;
Это даже в FAQ.
Этого больше нет в FAQ, потому что это неправильно. Подумайте, как это влияет на схватки :)
Вот вам версия на C++. В нем есть набор слов без прописных букв, таких как местоимения и предлоги. Однако я бы не рекомендовал автоматизировать этот процесс, если вы имеете дело с важными текстами.
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
#include <set>
using namespace std;
typedef vector<pair<string, int> > subDivision;
set<string> nonUpperCaseAble;
subDivision split(string & cadena, string delim = " "){
subDivision retorno;
int pos, inic = 0;
while((pos = cadena.find_first_of(delim, inic)) != cadena.npos){
if (pos-inic > 0){
retorno.push_back(make_pair(cadena.substr(inic, pos-inic), inic));
}
inic = pos+1;
}
if (inic != cadena.length()){
retorno.push_back(make_pair(cadena.substr(inic, cadena.length() - inic), inic));
}
return retorno;
}
string firstUpper (string & pal){
pal[0] = toupper(pal[0]);
return pal;
}
int main()
{
nonUpperCaseAble.insert("the");
nonUpperCaseAble.insert("of");
nonUpperCaseAble.insert("in");
// ...
string linea, resultado;
cout << "Type the line you want to convert: " << endl;
getline(cin, linea);
subDivision trozos = split(linea);
for(int i = 0; i < trozos.size(); i++){
if (trozos[i].second == 0)
{
resultado += firstUpper(trozos[i].first);
}
else if (linea[trozos[i].second-1] == ' ')
{
if (nonUpperCaseAble.find(trozos[i].first) == nonUpperCaseAble.end())
{
resultado += " " + firstUpper(trozos[i].first);
}else{
resultado += " " + trozos[i].first;
}
}
else
{
resultado += trozos[i].first;
}
}
cout << resultado << endl;
getchar();
return 0;
}
Я думаю, что использование CultureInfo не всегда надежно, это простой и удобный способ манипулировать строкой вручную:
string sourceName = txtTextBox.Text.ToLower();
string destinationName = sourceName[0].ToUpper();
for (int i = 0; i < (sourceName.Length - 1); i++) {
if (sourceName[i + 1] == "") {
destinationName += sourceName[i + 1];
}
else {
destinationName += sourceName[i + 1];
}
}
txtTextBox.Text = desinationName;
В Excel есть встроенная формула PROPER(n).
Был очень рад увидеть, что мне не пришлось писать это самому!
http://titlecase.com/ имеет API
В Silverlight нет ToTitleCase в классе TextInfo.
Вот простой способ на основе регулярного выражения.
Примечание. В Silverlight нет предварительно скомпилированных регулярных выражений, но для меня эта потеря производительности не является проблемой.
public string TitleCase(string str)
{
return Regex.Replace(str, @"\w+", (m) =>
{
string tmp = m.Value;
return char.ToUpper(tmp[0]) + tmp.Substring(1, tmp.Length - 1).ToLower();
});
}
Это отлично! Наконец, кое-что «простое», которое я могу использовать в LightSwitch. Однако одна маленькая придирка. На самом деле это правильный регистр, а не регистр заголовка. Можете ли вы придумать простой способ заставить его исключить такие вещи, как «a», «the» и т. д.? Подходящий случай: это тестовое предложение Заголовок: это тестовое предложение
К сожалению, не удалось заставить "" создавать новые строки.
Как в Excel ПРАВИЛЬНО:
public static string ExcelProper(string s) {
bool upper_needed = true;
string result = "";
foreach (char c in s) {
bool is_letter = Char.IsLetter(c);
if (is_letter)
if (upper_needed)
result += Char.ToUpper(c);
else
result += Char.ToLower(c);
else
result += c;
upper_needed = !is_letter;
}
return result;
}
Вот реализация на Python: https://launchpad.net/titlecase.py
И порт этой реализации, которую я только что сделал на C++: http://codepad.org/RrfcsZzO
В Java вы можете использовать следующий код.
public String titleCase(String str) {
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (i == 0) {
chars[i] = Character.toUpperCase(chars[i]);
} else if ((i + 1) < chars.length && chars[i] == ' ') {
chars[i + 1] = Character.toUpperCase(chars[i + 1]);
}
}
return new String(chars);
}
Вот простой пример того, как это сделать:
public static string ToTitleCaseInvariant(string str)
{
return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str);
}
В C#
using System.Globalization;
using System.Threading;
protected void Page_Load(object sender, EventArgs e)
{
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
Response.Write(textInfo.ToTitleCase("WelcometoHome<br />"));
Response.Write(textInfo.ToTitleCase("Welcome to Home"));
Response.Write(textInfo.ToTitleCase("Welcome@to$home<br/>").Replace("@","").Replace("$", ""));
}
В C# вы можете просто использовать
CultureInfo.InvariantCulture.TextInfo.ToTitleCase(str.ToLowerInvariant())
Недоступно в Silverlight. См. Другие ответы на C#