2010-04-30 9 views
17

Ich schreibe eine grundlegende Funktion, um Millionen von Namen in einem einmaligen Batch-Prozess von ihrer aktuellen Großbuchstabenform in einen richtigen Mischfall umzuwandeln. Ich kam mit der folgenden Funktion auf:Wie kann diese Methode zur Umwandlung eines Namens in den richtigen Fall verbessert werden?

public string ConvertToProperNameCase(string input) 
{ 
    char[] chars = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(input.ToLower()).ToCharArray(); 

    for (int i = 0; i + 1 < chars.Length; i++) 
    { 
     if ((chars[i].Equals('\'')) || 
      (chars[i].Equals('-'))) 
     {      
      chars[i + 1] = Char.ToUpper(chars[i + 1]); 
     } 
    } 
    return new string(chars); 
} 

Es ist in den meisten Fällen funktioniert wie:

  1. JOHN SMITH → John Smith
  2. SMITH, JOHN T → Smith, John T
  3. JOHN O'BRIAN → John O'Brian
  4. John Doe-Smith → John Doe-Smith

Es gibt einige Grenzfälle, die nicht funktionieren:

  1. JASON MCDONALD → Jason Mcdonald (Richtig: Jason McDonald)
  2. Oscar De La Hoya → Oscar De La Hoya (Richtig: Oscar de la Hoya
  3. )
  4. MARIE DiFranco → Marie Difranco (Richtig: Marie DiFranco)

Diese werden nicht erfasst, und ich bin nicht sicher, ob ich das kann h andle all diese seltsamen Randfälle. Wie kann ich ändern oder hinzufügen, um mehr Randfälle zu erfassen? Ich bin mir sicher, dass es Tonnen von Randfällen gibt, an die ich nicht einmal denke. Das gesamte Gehäuse sollte auch den nordamerikanischen Konventionen folgen, was bedeutet, dass, wenn bestimmte Länder ein anderes Großformat erwarten, das nordamerikanische Format Vorrang hat.

+0

Etwas geringfügiges Detail, aber FxCop sollte Sie über 'input.ToLower()' warnen; Sie sollten auch die Kultur angeben, die dort verwendet werden soll. Ich bin mir nicht sicher, ob das auch für 'Char.ToUpper' gilt. –

+0

Ich weiß, dass dies nicht hilft, aber ... Dies ist ein Grund, warum es wichtig ist, gute Daten für den Anfang zu haben. Wenn die Namen mit Groß- und Kleinbuchstaben gespeichert wurden, können Sie leicht in Großbuchstaben wechseln. Wenn Sie Ihre Namen in die erste/letzte Spalte aufteilen, ist es leicht, bei Bedarf mitzumachen, aber nicht so einfach umzukehren. –

+1

@Nelson aber wenn Sie keine Kontrolle haben, woher die Daten kamen, müssen Sie fällig machen :( – Kelsey

Antwort

9

Ich denke, Sie werden hier wieder eine Mauer laufen, weil Sie normalerweise nicht in der Lage sein werden, richtig zu beurteilen, ob eine Umwandlung sinnvoll ist oder nicht.

Betrachten Sie Ihre Grenzfälle

JASON MCDONALD -> Jason Mcdonald (Richtig: Jason McDonald)

Sie einfach für Mc am Anfang Ihres Namens und wenden Sie dann Ihre Korrektur überprüfen könnten, , Recht? Aber was ist, wenn Ihre Person Mcizck heißt (ich habe das natürlich erfunden) und das sollte nicht auf Mc Izck korrigiert werden, aber sollte so bleiben wie es ist?

Es gibt keine 100% perfekte Lösung für dieses Problem. Was Sie hier haben, ist ein Problem mit der natürlichen Sprache, und sie sind wirklich schwer zu lösen, besonders für einen Computer. Kulturen sind zu verschieden, um richtig modelliert zu werden. Selbst wenn Sie sagen, dass nordamerikanische Konventionen Vorrang haben, haben Sie einen hohen Prozentsatz von "falsch positiven". Unsere Gesellschaft besteht aus einer riesigen Mischung von Kulturen, es reicht einfach nicht aus zu sagen "Nordamerika hat Vorrang".

Ohne die Randfälle zu behandeln, denke ich, dass Ihre aktuelle Lösung in 99% der Fälle funktioniert. Alle weiteren Randfälle sollten manuell korrigiert werden, wenn 100% korrekte Namen wirklich benötigt werden.

0

Nun, zuerst wird dieser Code eine Ausnahme auslösen, wenn der Name ein 'oder - am Ende hat, da es versuchen wird, das nächste (nicht vorhandene) Element im Array groß zu schreiben.siehe bearbeiten Kommentar unten

Other than that ...

Ich glaube nicht, dass Sie wirklich für DiFranco erklären kann, es sei denn Sie nur Konto für DiFranco und kein anderer Di ‚s (gibt es irgendein?). Außerdem denke ich, dass es sicher ist anzunehmen, dass jeder Mc einen nächsten Großbuchstaben verdient. Und ich denke auch, dass es sicher ist, de und la zu sagen, wenn der Raum um sie herum niedriger ist.

Aber am Ende des Tages scheinen Sie versuchen, Kulturen zu verwenden, die mir anzeigt, dass Sie nicht nur Englisch verwenden. Wenn das der Fall ist, dann denke ich, dass Sie viel mehr Probleme haben werden als Sie denken. Wenn Sie nur Englisch (oder dieses Modul ist das Englisch-Modul und es gibt andere für andere Sprachen), dann sind Sie vielleicht so nah wie Sie bekommen werden (abgesehen von Mc etc.)

+0

DiBella ist ein weiteres 'Di' (schöne Erinnerungen an ein Mädchen mit diesem Nachnamen aus der Highschool ;-)) – DaveDev

+1

@statichippo Ich glaube nicht, dass es eine Ausnahme verursachen wird (nur getestet), beachten Sie den Fall 'i + 1 , so dass es immer 1 Zeichen vom Ende zurück gibt. – Kelsey

+0

Whoops, habe das nicht bemerkt. redigiert – hackerhasid

0

Sie könnten

  • Split auf dem Trennzeichen "", "" und "-"
  • Titel Fall jeden Teil
  • alle Fälle Ihrer Kante für jede Phrase Griff
3

Es gibt keine allgemeine Lösung dieses Problem. Sogar innerhalb der üblichen Randfälle wie "Mc" gibt es Gegenbeispiele. Ich hatte einen Freund im College mit einem "Mc" Namen, der den folgenden Charakter nicht groß geschrieben hat; Offensichtlich war es vor Generationen in der Immigration vermasselt und alle halten sich an die historische, inkorrekte Schreibweise.

Einer der Vornamen meines Kollegen ist zwei traditionelle Vornamen CamelCased zusammen. Du wirst nie in der Lage sein, das zu erklären.

Dieses Problem entspricht dem Upscaling einer Videodatei; Sie können sich dem besten nähern, was Sie können, aber Sie können nicht magischerweise Informationen erzeugen, die nicht an erster Stelle gespeichert wurden.

+3

Sie meinen, dass Sie 100x nicht automatisch zu einem Bild niedriger Qualität "vergrößern" und "zoomen" können, wie sie es im Fernsehen tun? –

1

Sie können Regeln erstellen, die Sie näher bringen, aber Sie können nicht 100% erhalten. Sie können beispielsweise eine Liste mit Präfixen (Mc, Di usw.) erstellen.

  1. Wenn das Präfix in einem Vokal endet und der nächste Buchstabe ein Vokal ist, Kleinbuchstaben.
  2. Wenn das Präfix in einem Vokal endet und der nächste Buchstabe ein Konsonant ist, Großbuchstabe.
  3. Wenn das Präfix in einem Konsonanten endet, ist der nächste Buchstabe ein Großbuchstabe.

Etc ... aber Sie würden wahrscheinlich eine gute Liste der Präfixe erhalten wollen und Sie werden immer Ausnahmen haben.

0

Das Problem ist, wie alle anderen gesagt haben, dass Sie nie alle Fälle von Kanten erfassen werden. Ich würde vorschlagen, gehen here, den vollständigen Datensatz herunterladen und vergleichen. Aber dieser Datensatz ist alles in Großbuchstaben. Da dies ein einmaliger Prozess ist, würde ich stattdessen die Liste von dem oben genannten Link herunterladen, der die Top 1000 Nachnamen enthält, sie manuell korrigieren und Ihre Datensätze mit dieser Liste verarbeiten. Markieren Sie die nicht verarbeiteten Datensätze und prüfen Sie, ob die Anzahl klein genug ist, um von Hand verwaltet werden zu können.

0

Ihre Frage ist, ob Ihr Programm verbessert werden kann. Meine Antwort ist: "In welche Richtung geht es besser?" Sie haben zwei verschiedene Randfälle, die sich gegenseitig ausschließen.Entweder werden Sie die Leute mit ungewöhnlichen Kapitalisierungsregeln nicht fangen, oder Sie werden nicht die Leute fangen, die sich nicht an ungewöhnliche Kapitalisierungsregeln halten.

Ich ging mit jemandem mit dem Nachnamen "De La Rosa" zur Schule. In Anbetracht Ihres Beispiels von de la Hoya, wäre es fair anzunehmen, dass "de la Rosa" auch der Familienname von jemandem da draußen ist. Also, wenn Sie eine Methode implementieren, um "de la" zu dekapitisieren, dann vermissen Sie meinen Freund und ich werde traurig sein. Und wenn Sie die Dekapitalisierung nicht durchführen, verpassen Sie diese anderen Leute. Und der Himmel verbietet dir, auf De la Rosa zu stoßen, der von keiner der beiden Methoden erwischt wird ...

Also denk mal, in welche Richtung denkst du, "Verbesserung" für deinen Code zu sein? Wenn Sie der Meinung sind, dass Sie Edge-Cases für ungewöhnliche Groß- und Kleinschreibung behandeln und diejenigen, die sich nicht daran halten, manuell abrechnen, helfen Ihnen die anderen Antworten, die Ihnen dabei helfen. Wenn Sie der Meinung sind, dass Sie ungewöhnliche Groß- und Kleinschreibung manuell behandeln sollten, muss Ihr Code nicht geändert werden. In jedem Fall müssen Sie manuell etwas tun.

4

Ich hoffe, dass Sie diese Konvertierung durchführen, weil die Software geändert wird, damit die Benutzer ihre Namen mit dem richtigen Gehäuse eingeben können.

Das gesagt, die einzige zuverlässige Lösung wäre, die Benutzer zu benachrichtigen, dass Sie die Darstellung ihres Namens geändert haben. Sie können dann das Gehäuse bearbeiten, wenn es falsch ist. (Sie könnten sie anrufen, mailen, warten, bis sie Ihre Software das nächste Mal verwenden, usw.)

Wenn Sie nicht zulassen, dass die Benutzer ihre eigenen Namen aktualisieren, wäre die zweit zuverlässigste Methode, Listen zu sammeln (letzte) Namen aus öffentlichen Quellen. Wenn Sie genug davon finden können, sollten Sie in der Lage sein, mehr von den Randfällen abzudecken - sehen Sie einfach, ob der Name in Ihrer ordentlichen Liste vorhanden ist, und verwenden Sie dann dieses Gehäuse.

+1

Es ist eine Systemdatenmigration, bei der die "Kunden" keinen Zugriff auf diese Daten im alten oder neuen haben. Nur eine Batch-Bereinigung der Daten vor dem Import in das neue System. – Kelsey

+1

+1 Wichtig ist, dass wir die Wünsche der Kunden respektieren, wie ihre Namen buchstabiert oder großgeschrieben werden. –

+1

Wenn dies eine Batch-Bereinigung sein soll, sollten Sie den Fall überhaupt nicht ändern. All Caps bedeuten in jedem Fall, dass Fallinformationen nicht bekannt sind.Wenn Sie die Groß-/Kleinschreibung als relevant einstufen, werden Ihre Daten tatsächlich verschmutzt, weil Sie von Groß- und Kleinschreibung bei 0% auf> 0% Großbuchungsfehler gehen. –

0
<System.Runtime.CompilerServices.Extension()> _ 
Public Function ProperCase(ByVal value As String) As String 

    If String.IsNullOrWhiteSpace(value) Then 
     Return String.Empty 
    End If 

    value = value.Trim 

    Dim sb As New StringBuilder(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value.ToLower)) 

    '// Special cases ' and - 
    For i As Integer = 0 To sb.Length 
     Dim c As Char = sb(i) 
     If sb(i).Equals("'") Or sb(i).Equals("-") Then 
      'Upper Case Next character 
      sb(i + 1) = Char.ToUpper(sb(i + 1)) 
     End If 
    Next 

    If sb.ToString.StartsWith("Mac") Then 
     sb(3) = Char.ToUpper(sb(3)) 
    End If 

    If sb.ToString.StartsWith("Mc") Then 
     sb(2) = Char.ToUpper(sb(2)) 
    End If 

    Return sb.ToString 

End Function 
Verwandte Themen