Comment convertiriez-vous des noms dans un cas approprié en C #? P>
J'ai une liste de noms que j'aimerais prouver. p>
Par exemple: McDonalds à McDonalds ou O'Brien à O'Brien. P>
10 Réponses :
C'est un problème intéressant. Je ne pense pas qu'il y ait une solution "hors de la boîte". P>
J'ai favorisé l'article suivant qui peut être proche de ce que vous voulez: p>
Perte et trouvé Identité Processionné de format de cas approprié (implémentation iFormatProvider) < / p>
Je n'ai pas essayé le code et cette solution nécessite à peu près manuellement tous les cas. Mais c'est un début et peut-être que vous le trouverez utile. P>
Manuellement Manutention Les cas sont le seul moyen de le faire que je connais. Nous avons une bibliothèque interne qui fait à peu près la même chose (et nous finissons à ajouter de nouveaux bizarreries de temps en temps).
Il n'y a absolument aucun moyen pour un ordinateur juste de savoir par magie que le premier "D" dans "McDonalds" devrait être capitalisé. Donc, je pense qu'il y a deux choix. P>
Quelqu'un de côté peut avoir un logiciel ou une bibliothèque qui le fera pour vous. P> LI>
Sauf que votre seul choix est de prendre l'approche suivante: d'abord, je rechercherais le nom dans un dictionnaire de mots qui ont une capitalisation "intéressante". Évidemment, vous devriez vous fournir ce dictionnaire vous-même, à moins que l'on n'existe déjà. Deuxièmement, appliquez un algorithme qui corrige certains des noms évidents, tels que les noms celtiques commençant par O 'et Mac et MC, bien que l'algorithme dispose sans aucun doute de nombreux faux positifs. Enfin, capitalise la première lettre de chaque nom qui ne répond pas aux deux premiers critères. P> Li> ol>
S'il vous plaît, ne faites pas l'approche factice avec 'Mac'. Mon nom est constamment mutilé par des systèmes de messagerie stupides.
@ MaciejtryBiło: Les machines feront ce que vous.
La partie difficile de ceci est l'algorithme de décider de la capitalisation. La manipulation de chaîne elle-même est assez facile. Il n'y a pas de manière parfaite, car il n'y a pas de "règles" pour les cas. Une stratégie pourrait être un ensemble de règles, telles que "capitaliser la première lettre ... généralement" et "capitaliser la 3ème lettre si les deux premières lettres sont MC ... généralement" P>
Commencer avec un dictionnaire de vrais noms et les comparer à votre propre nom pour les matchs aidera. Vous pouvez également prendre un dictionnaire de vrais noms, générer une chaîne de Markhov à partir de celui-ci et lancer de nouveaux noms à la chaîne de Markhov afin de déterminer la capitalisation. C'est une solution folle et compliquée. P>
La solution parfaite parfaite consiste à utiliser des humains pour corriger les données. P>
Cela nécessite que votre programme soit capable d'interpréter la langue anglaise dans une certaine mesure. À tout le moins être capable de décomposer une corde dans un ensemble de mots. Il n'y a pas d'API intégré au framework .NET qui peut y parvenir.
Cependant, s'il y en avait, vous pouvez utiliser le code suivant. p> Ce n'est pas une solution parfaite, mais cela vous donne une idée générale du contour p> p>
Vous pouvez envisager d'utiliser un moteur de recherche pour vous aider. Soumettez une requête et voyez comment les résultats ont capitalisé le nom. P>
Je ne l'ai jamais fait. Cela ressemble à une tâche pour les nouveaux stagiaires!
J'ai écrit les méthodes d'extension suivantes. N'hésitez pas à les utiliser.
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();
}
}
Vous êtes génial! Merci!
Vous pouvez vérifier le nom de famille inférieur / mixte sur un dictionnaire (fichier) qui contient les boyaux corrects, puis renvoyez la valeur «réelle» du dictionnaire. P>
J'ai eu un rapide Google pour voir si l'on existe, mais sans être disponible! P>
Doh, vient de remarquer que Gregory a déclaré la même chose avec des observations supplémentaires (et utiles). J'ai gracieusement s'incliner:]
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
string txt = textInfo.ToTitleCase("texthere");
Bien que ce code puisse répondre à la question, fournissant un contexte supplémentaire concernant la raison et / ou la manière dont ce code répond à la question améliore sa valeur à long terme.
Cela ne traite pas de l'affaire "MC". Le titre le rendrait "McDonalds" pas "McDonalds"
Je prévois d'écrire une telle fonction, mais je ne vais probablement pas entrer dans trop de cas de bord ... ci-dessous dans le code Psuedo avec regex pour la correspondance ...
commencez par / \ b [AZ] + \ B / en tant que correspondance définie, chaque séquence de lettres sur une limite de mot, correspond à un ensemble. p> avec la chaîne de nom entiers remplacée correspondant à un autre remplacement sets comme ... p> qui devrait attraper la plupart des cas pour les noms en particulier ... mais une bonne base de données de boîtier de nom commun serait très agréable. P> < / p>
Voici ma solution. Ce disque codise les noms dans le programme, mais avec un peu de travail, vous pouvez conserver un fichier texte en dehors du programme et lire dans les exceptions de noms (c'est-à-dire des exceptions (c'est-à-dire Van, MC, Mac) et en boucle.