2010-08-02 12 views
14

J'ai besoin d'une fonction qui prendra une chaîne et "cas pascal". Le seul indicateur qu'un nouveau mot commence est un trait de soulignement. Voici quelques exemples de chaînes qui doivent être assainis:Fonction pour faire un cas Pascal? (C#)

  1. price_old => Devrait être PriceOld
  2. rank_old => Devrait être RankOld

j'ai commencé à travailler sur une fonction qui rend le premier caractère majuscules:

public string FirstCharacterUpper(string value) 
{ 
if (value == null || value.Length == 0) 
    return string.Empty; 
if (value.Length == 1) 
    return value.ToUpper(); 
var firstChar = value.Substring(0, 1).ToUpper(); 
return firstChar + value.Substring(1, value.Length - 1); 
} 

la chose la fonction ci-dessus ne fait pas le trait de soulignement est et enlever « ToUpper » le caractère à droite du trait de soulignement.

Aussi, toutes les idées sur la façon de pascal d'une chaîne qui n'a pas d'indicateurs (comme le trait de soulignement). Par exemple:

  1. companysource
  2. financialtrend
  3. accountingchangetype

Le principal défi ici consiste à déterminer où se termine mot et un autre commence. Je suppose que j'aurais besoin d'une sorte de dictionnaire de recherche pour déterminer où les nouveaux mots commencent? Existe-t-il des bibliothèques pour faire ce genre de chose?

Merci,

Paul

+4

Un commentaire rapide - c'est le cas Pascal. L'étui à chameaux commence par une minuscule, par ex. 'rankOld'. –

+1

@Jon O, bon à savoir ... mise à jour ... –

+1

Un autre commentaire rapide - il n'est pas nécessaire de spécifier une longueur quand vous voulez que la sous-chaîne entière soit à partir d'un certain point de départ. Donc, au lieu de value.Substring (1, value.Length - 1) vous pouvez simplement faire value.Substring (1). – Anton

Répondre

23

Vous pouvez utiliser la méthode TextInfo.ToTitleCase puis supprimer les caractères '_'.

Ainsi, en utilisant les méthodes d'extension que j'ai:

http://theburningmonk.com/2010/08/dotnet-tips-string-totitlecase-extension-methods

vous pouvez faire somethingl IKE ceci:

var s = "price_old"; 
s.ToTitleCase().Replace("_", string.Empty); 
+0

Approche intéressante! –

+0

@theburningmonk J'aime ce que je vois jusqu'à maintenant ... pourrait finir par utiliser cette approche. –

+0

@theburningmonk Cela fonctionne comme un charme! Merci encore. –

11

Eh bien la première chose est facile:

string.Join("", "price_old".Split(new [] { '_' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Substring(0, 1).ToUpper() + s.Substring(1)).ToArray()); 

retours PriceOld

chose deuxième est beaucoup plus difficile. Comme companysource pourrait être CompanySource ou peut-être CompanysOurce, peut être automatisé mais est tout à fait défectueux. Vous aurez besoin d'un English dictionary, et faire une certaine supposition (ah eh bien, je veux dire beaucoup) sur laquelle la combinaison de mots est correcte.

+0

Comme vous l'avez si bien fait remarquer, traiter avec des mots est difficile. Je suppose qu'il n'y a pas moyen de contourner cela, je vais devoir faire une sorte de recherche de dictionnaire. Je suppose que j'espérais que quelqu'un avait déjà développé quelque chose que je pourrais utiliser. –

+0

+1: pour signaler la solution du dictionnaire pour * deuxième chose * –

4

Essayez ceci:

public static string GetPascalCase(string name) 
{ 
    return Regex.Replace(name, @"^\w|_\w", 
     (match) => match.Value.Replace("_", "").ToUpper()); 
} 

Console.WriteLine(GetPascalCase("price_old")); // => Should be PriceOld 
Console.WriteLine(GetPascalCase("rank_old")); // => Should be RankOld 
+0

Seulement, cela est quatre fois plus lent que le fractionnement et la sous-chaîne, et deux fois plus lent lors de la compilation de l'expression rationnelle (faire 100 000 fois). –

+2

Puis-je avoir votre référence, @Jan? –

1

Avec underscores :

s = Regex.Replace(s, @"(?:^|_)([a-z])", 
     m => m.Groups[1].Value.ToUpper()); 

Sans underscores:

Vous êtes sur votre propre là-bas.Mais allez-y et cherchez; Je serais surpris si personne n'a a fait cela avant.

0

Pour votre 2ème problème de division des mots concaténés, vous pouvez utiliser nos meilleurs amis Google & Co. Si votre entrée concaténée est composée de mots anglais usuels, les moteurs de recherche ont un bon taux de succès pour les mots simples comme alternative Rechercher

Si vous entrez dans l'entrée de votre échantillon, Google et Bing suggère ce qui suit:

original    | Google    | Bing 
===================================================================== 
companysource  | company source  | company source 
financialtrend  | financial trend  | financial trend 
accountingchangetype | accounting changetype | accounting change type 

Voir this exaple.

L'écriture d'un petit grattoir d'écran pour cela devrait être assez facile.

+0

http://stackoverflow.com/questions/3856630/how-to-separate-words-in-a-sentence-with-spaces - 8 lignes pour un script shell. –

0

pour ceux qui ont besoin d'une solution non regex

public static string RemoveAllSpaceAndConcertToPascalCase(string status) 
     { 
      var textInfo = new System.Globalization.CultureInfo("en-US").TextInfo; 
      var titleCaseStr = textInfo.ToTitleCase(status); 
      string result = titleCaseStr.Replace("_","").Replace(" ", ""); 

      return result; 
     }