Фамилия с заглавной буквы

Таким образом, я получаю данные о фамилии всеми заглавными буквами из базы данных. Мне нужно отформатировать текст, чтобы первая буква каждой части имени была заглавной. В настоящее время у меня есть приведенный ниже код, который учитывает людей с двойными фамилиями (например, SMITH-JONES становится Smith-Jones), но при проверке результатов я заметил, что у меня все еще есть ошибка, когда речь идет о таких именах, как VAN BEBBER, который становится Van bebber. Какие-либо предложения?

var fullLast = Last.Split('-');
var lastFormatted = new StringBuilder();

for (var i = 0; i < fullLast.Length; i++)
{
    fullLast[i] = char.ToUpper(fullLast[i][0]) + fullLast[i].Substring(1).ToLower();
    lastFormatted.Append(fullLast[i]);
    if (i != fullLast.Length - 1)
        lastFormatted.Append("-");
}

return string.Format(
    "{0} {1}",
    char.ToUpper(First[0]) + First.Substring(1).ToLower(),
    lastFormatted);

person Desquid    schedule 13.10.2015    source источник
comment
Что мешает вам исправить это так же, как вы исправили двойные фамилии? (Т.е. разделение на оба символа.)   -  person 31eee384    schedule 13.10.2015
comment
В .NET уже есть метод ToTitleCase.   -  person Dai    schedule 13.10.2015


Ответы (3)


Это известная проблема с именами — вещи крайне противоречивы. Прочтите эту статью для получения дополнительной информации: http://www.w3.org/International/questions/qa-personal-names

В вашем примере вы ссылаетесь на фамилию «VAN BEBBER», которую вы хотите написать с большой буквы как «Van Bebber». Однако, как указано в статье, существуют и другие комбинации из других регионов мира, которые разрушили бы большинство попыток стандартизации — например, фамилия «БИН ОСМАН» была бы правильно написана с заглавной буквы как «бин Osman» — без заглавной буквы «b» в слове «bin», что означает «сын» и, следовательно, не очень хорошо вписывается в прозападную концепцию фамилии.

Вы упомянули, что разделили фамилии тире, что, скорее всего, исходит из идеи написания фамилии через дефис - вы также проверяете имя на тире? На сайте приводится пример имени «Мария-Хосе Карреньо Киньонес», который довольно сложно разобрать из-за двойного имени (разделенного дефисом), а также двойной фамилии (разделенного пробелом). Как бы ваша программа справилась с таким названием?

Чтобы ответить на ваш вопрос более прямо, не вводя больше крайних случаев - вы уже знаете, как разделить строку с помощью тире - если вы хотите покрыть регистр фамилий пробелами, вам следует дополнительно разделить строку фамилии пробелами, и только затем сделайте заглавной первую букву разных разделенных строк.

В качестве альтернативы, как упомянул Дай в комментарии, вы можете использовать метод ToTitleCase — дополнительная информация здесь: https://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase(v=vs.110).aspx Это, скорее всего, лучшее решение, чем пытаться сделать свое собственное. Однако эта страница ссылается на тот факт, что не все языки пишутся с заглавных букв одинаково (и действительно, разные фамилии могут происходить из разных областей/культур/языков), и поэтому установка правильного языка не всегда может привести к правильному использованию заглавных букв в фамилии. Обратите внимание, что "BIN OSMAN" будет написано с заглавной буквы как "Bin Osman", что технически неверно.

Вот быстрый пример с этой страницы:

// Defines the String* with mixed casing.
String^ myString = "wAr aNd pEaCe";

// Creates a TextInfo based on the "en-US" culture.
/**** Personal Note - en-US may not be the correct culture for every last name! ****/
CultureInfo^ MyCI = gcnew CultureInfo( "en-US",false );
TextInfo^ myTI = MyCI->TextInfo;

// Changes a String* to lowercase. Outputs "War and Peace"
Console::WriteLine( "\"{0}\" to titlecase: {1}", myString, myTI->ToTitleCase( myString )
person Jake    schedule 13.10.2015

Я думаю, вы можете использовать метод ToTitleCase....

CultureInfo cultureInfo = CultureInfo.CurrentCulture; //Or use a specific culture
var str1 = cultureInfo.TextInfo.ToTitleCase("VAN BEBBER".ToLower(cultureInfo));
var str2 = cultureInfo.TextInfo.ToTitleCase("SMITH-JONES".ToLower(cultureInfo));
person Eser    schedule 13.10.2015
comment
var str3 = CultureInfo.TextInfo.ToTitleCase(Нэнси О'Нил.ToLower()); хммммм.... ты уверен, что это работает? - person g2000; 13.10.2015
comment
Он работает на основе определенного набора правил использования заглавных букв для каждого языка. O'Neill на самом деле не английское слово, поэтому CultureInfo.CurrentCulture может не содержать правила или набора правил, которые заставляли бы его правильно писать с заглавной буквы. Возможно, culture не содержит правильных правил для этого примера. Это удивительно сложная проблема. - person Jake; 13.10.2015

Почему бы вам не сделать разделение пробелом, а затем «-». Таким образом, вы могли бы захватить все экземпляры.

См. этот пример:

var names = fullName.Split(' ');
        var formatted = new StringBuilder();
        foreach(string name in names)
        {
            if(name.Contains('-'))
            {
                var nonHyphanatedNames = name.Split('-');
                    foreach (var nonHyphanatedName in nonHyphanatedNames)
                    {
                        formatted.Append(char.ToUpper(nonHyphanatedName[0]) + nonHyphanatedName.Substring(1).ToLower() + '-');
                    }

            }
            else
            {
                formatted.Append(char.ToUpper(name[0]) + name.Substring(1).ToLower() + ' ');
            }


        }
        //remove last field
        formatted.Remove(formatted.Length - 1, 1);
        Console.Write(formatted);
person chixcancode    schedule 13.10.2015
comment
Это, безусловно, зафиксирует случаи, упомянутые Дескидом, однако, как я уже упоминал в своем ответе, на самом деле существует множество крайних случаев, когда речь идет об именах по всему миру. Ван Беббер — как раз один из таких случаев. - person Jake; 13.10.2015
comment
На самом деле код, который я предоставил, охватывает и эти крайние случаи. Поскольку «Ван Беббер» отделяется пробелом (« »), он работает - person chixcancode; 13.10.2015
comment
Но не охватывает такие случаи, как бин Осман (из моего ответа) или О'Нил (из комментария g2000 к другому ответу) - дело в том, что капитализация имен, к сожалению, не так проста, как разделение пробелами и/или тире, а затем использование заглавных букв - person Jake; 13.10.2015