2009-09-24 3 views
10

어떻게하면 C#에서 적절한 이름으로 이름을 변환하겠습니까?Cc의 ProperCase에 대한 mcdonalds

나는 증명할 이름 목록이 있습니다.

예 : 맥도날드에서 맥도날드로 또는 오브라이언에서 오브라이언으로.

답변

7

"맥도날드"의 첫 번째 "D"가 대문자이어야한다는 것을 컴퓨터가 마술 적으로 알 수있는 방법은 절대적으로 없습니다. 그래서 두 가지 선택이 있다고 생각합니다.

  1. 누군가가 소프트웨어 나 라이브러리를 가지고있을 수 있습니다.

  2. 귀하의 유일한 선택은 다음과 같은 접근 방식을 취하는 것입니다. 첫째, "흥미로운"대문자가있는 단어 사전에서 이름을 찾습니다. 분명히 이미 존재하지 않는 한이 사전을 직접 제공해야합니다. 둘째, O '와 Mac 및 Mc로 시작하는 셀틱 이름과 같은 명백한 알고리즘을 수정하는 알고리즘을 적용하십시오. 충분한 알고리즘 이름이 주어 지더라도 그러한 알고리즘은 의심의 여지가 많은 오 탐지를 갖습니다. 마지막으로 처음 두 가지 기준을 충족하지 않는 모든 이름의 첫 글자를 대문자로하십시오.

+6

'Mac'으로 가짜 방식을 사용하지 마십시오. 내 이름은 바보 같은 메일 시스템에 의해 끊임없이 불구가되어 가고 있습니다. –

+3

@ MaciejTrybiło : MacHines가 나중에 할 것입니다. – supercat

2

이것은 흥미로운 문제입니다. 나는 '상자 밖으로'해결책이 있다고 생각하지 않는다. 내가 코드와 거의 수동으로 모든 경우를 처리 필요이 솔루션을 시도하지 않은

Lost and Found Identity Proper Case Format Provider (IFormatProvider implementation)

:

나는 당신이 원하는에 가까운 수의 다음 문서를 북마크. 그러나 그것은 시작이며 아마 유용 할 것입니다.

+0

사례를 수동으로 처리하는 것이 내가 아는 유일한 방법입니다. 거의 동일한 작업을 수행하는 내부 라이브러리가 있습니다. (때때로 새로운 단점을 추가해야합니다.) – Godeke

1

대소 문자를 구하는 알고리즘이 중요합니다. 문자열 조작 자체는 매우 쉽습니다. 경우에는 "규칙"이 없기 때문에 완벽한 방법은 없습니다. 하나의 전략은 "첫 글자를 대문자로 ... 일반적으로"와 "처음 두 글자가 보통이면 ... 세 번째 글자를 대문자로 바꾸는 것과 같은 일련의 규칙 일 수 있습니다."

실제 이름으로 시작하는 사전 그 (것)들을 성냥을위한 당신의 자신의 이름과 비교하는 것은 도울 것이다. 또한 실제 이름의 사전을 가져 와서 Markhov 체인을 생성하고 Markhov 체인에서 새로운 이름을 던져 대문자를 판별 할 수 있습니다. 그것은 미친, 복잡한 해결책이다.

최고의 완벽한 솔루션은 인간을 사용하여 데이터를 수정하는 것입니다.

0

이렇게하려면 프로그램에서 영어를 어느 정도 해석 할 수 있어야합니다. 적어도 문자열을 단어 집합으로 분해 할 수 있어야합니다. 이를 달성 할 수있는 .Net Framework에 내장 된 API는 없습니다.

그러나 그랬다면 다음 코드를 사용할 수 있습니다.

public string ProperCase(string str, Func<string,bool> isWord) { 
    var word = new StringBuilder(); 
    var cur = new StringBuilder(); 
    for (var i = 0; i < str.Length; i++) { 
    cur.Append(cur.Length == 0 ? Char.ToUpper(str[i]) : str[i])); 
    if (isWord(cur.ToString()) { 
     word.Append(cur.ToString()); 
     cur.Length = 0; 
    } 
    } 
    if (cur.Length > 0) { 
    word.Append(cur); 
    } 
    return word.ToString(); 
} 

그것은 완벽한 해결책은 아니지만 그것은 당신에게 당신은 당신을 도울 검색 엔진을 사용하여 고려할 수 윤곽

9

의 일반적인 아이디어를 제공합니다. 검색어를 제출하고 그 결과가 어떻게 대문자로 표시되는지 확인하십시오.

+0

흥미로운 아이디어. 이것이 어떻게 행해지는지에 대한 샘플이 있습니까? –

+2

나는 그것을 한 번도 해본 적이 없다. 새로운 인턴을위한 작업처럼 들립니다! – tster

+0

그건 아주 영리합니다. –

6

다음 확장 방법을 작성했습니다.자유롭게 사용하십시오. 그것은 올바른 케이스를 가지고

public static class StringExtensions 
{ 
    public static string ToProperCase(this string original) 
    { 
    if(original.IsNullOrEmpty()) 
     return original; 

    string result = _properNameRx.Replace(original.ToLower(CultureInfo.CurrentCulture), HandleWord); 
    return result; 
    } 

    public static string WordToProperCase(this string word) 
    { 
    if(word.IsNullOrEmpty()) 
     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(); 
    } 
} 
0

당신은 사전 (파일)에 대한 혼합/소문자 성을 확인할 수 있습니다 후 사전에서 '진짜'값을 반환합니다.

나는 존재하는 경우에, 그러나 아무 소용이든지 보는 빠른 google가 있었다! 나는 그런 기능을 작성하는 계획입니다, 그러나 아마 일치하는 정규식과 사이비 코드에 아래 ... 너무 많은 에지의 경우에 가지 않을

+1

Doh, 그레고리 (Gregory)가 추가 (유용한) 관찰을 통해 같은 것을 말한 것을 눈치 챘다. 나는 정상적으로 찬성한다 :] – Lee

0
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture; 
TextInfo textInfo = cultureInfo.TextInfo; 
string txt = textInfo.ToTitleCase("texthere"); 
+0

이 코드는 질문에 대답 할 수 있지만, 왜 그리고/또는 어떻게이 코드가 질문에 대답하는지에 대한 추가적 맥락을 제공하면 장기적인 가치가 향상된다. – Bono

0

...와

시작/\ b [AZ] + \ b /와 일치하므로 단어 경계에 대한 문자의 각 시퀀스는 집합으로 일치합니다. 교체 된 전체 이름 문자열로

if the string is all uppercase... 
    lower-case the string 
    upper-case the first letter 
    do the following beginning of string replacements 
    Vanb -> VanB 
    Vanh -> VanH 
    Mc? -> Mc? (uppercase wildcard character) 
    Mac[^kh] -> Mac? (uppercase wildcard match) 

은 ... 교체 등의 설정 기타에 대해 일치 않습니다 특히 이름에 대한 대부분의 경우를 잡을해야

"De La " -> "de la " 

...하지만 일반적인 이름의 좋은 데이터베이스 케이싱은 매우 좋을 것입니다.

0

내 해결책은 여기에 있습니다. 이렇게하면 이름이 프로그램에 하드 코드되지만 약간의 작업만으로 프로그램 외부에 텍스트 파일을 보관하고 예외 이름 (예 : Van, Mc, Mac)을 읽고이를 반복 할 수 있습니다.

public static String toProperName(String name) 
{ 
    if (name != null) 
    { 
     if (name.Length >= 2 && name.ToLower().Substring(0, 2) == "mc") // Changes mcdonald to "McDonald" 
      return "Mc" + Regex.Replace(name.ToLower().Substring(2), @"\b[a-z]", m => m.Value.ToUpper()); 

     if (name.Length >= 3 && name.ToLower().Substring(0, 3) == "van") // Changes vanwinkle to "VanWinkle" 
      return "Van" + Regex.Replace(name.ToLower().Substring(3), @"\b[a-z]", m => m.Value.ToUpper()); 

     return Regex.Replace(name.ToLower(), @"\b[a-z]", m => m.Value.ToUpper()); // Changes to title case but also fixes 
                        // appostrophes like O'HARE or o'hare to O'Hare 
    } 

    return ""; 
} 
관련 문제