2010-08-02 25 views
14

Necesito una función que tomará una cadena y la "caja pascal". El único indicador de que una nueva palabra comienza es un guión bajo. Aquí están algunas cadenas de ejemplo que deben ser saneados:Función para hacer Pascal Case? (C#)

  1. price_old => Debe ser PriceOld
  2. rank_old => Debe ser RankOld

empecé a trabajar en una función que hace que el primer carácter mayúscula:

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); 
} 

lo de la función anterior no hacer es quitar el subrayado y "ToUpper" el carácter situado a la derecha del guión.

Además, cualquier idea sobre cómo pasar el caso de una cadena que no tiene ningún indicador (como el guión bajo). Por ejemplo:

  1. companysource
  2. financialtrend
  3. accountingchangetype

, el principal problema es determinar dónde termina una palabra y empieza otro. Supongo que necesitaría algún tipo de diccionario de búsqueda para determinar dónde comienzan las palabras nuevas. ¿Ya hay bibliotecas para hacer este tipo de cosas?

Gracias,

Paul

+4

Un comentario rápido - que es el caso de Pascal. El estuche Camel comienza con una minúscula, p. 'rankOld'. –

+1

@Jon O, es bueno saber ... actualizar ... –

+1

Otro comentario rápido: no es necesario especificar una longitud cuando desea que toda la subcadena se encuentre en un determinado punto de inicio. Entonces, en lugar de value.Substring (1, value.Length - 1) simplemente puede hacer value.Substring (1). – Anton

Respuesta

23

Puede utilizar el método TextInfo.ToTitleCase y luego eliminar los caracteres '_'.

Por lo tanto, el uso de los métodos de extensión que tengo:

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

Usted puede hacer esto somethingl ike:

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

Interesante enfoque! –

+0

@theburningmonk Me gusta lo que estoy viendo hasta ahora ... podría terminar utilizando este enfoque. –

+0

@theburningmonk ¡Funciona como un encanto! Gracias de nuevo. –

11

Bueno lo primero es fácil:

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

vuelve PriceOld

Lo segundo es mucho más difícil. Como companysource podría ser CompanySource o quizás CompanysOurce, se puede automatizar pero es bastante defectuoso. Necesitará un English dictionary, y adivine (bueno, me refiero a mucho) en qué combinación de palabras es la correcta.

+0

Como tan eficazmente señaló, lidiar con las palabras es difícil. Supongo que no hay forma de evitarlo, tendré que hacer algún tipo de búsqueda en el diccionario. Supongo que esperaba que alguien ya haya desarrollado algo que pueda usar. –

+0

+1: para señalar la solución de diccionario para * segunda cosa * –

4

Prueba esto:

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

Solo que esto es cuatro veces más lento que simplemente dividir y substringir, y el doble de lento al compilar la expresión regular (esto 100.000 veces). –

+2

¿Puedo tener su punto de referencia, @Jan? –

1

Con guiones :

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

Sin subrayados:

Usted está en su propia allí.Pero adelante y busca; Me sorprendería si nadie ha hecho esto antes.

0

Para su segundo problema de división de palabras concatenas, puede utilizar nuestros mejores amigos Google & Co. Si su entrada concatenada se compone de palabras comunes en inglés, los motores de búsqueda tienen una buena tasa de aciertos para las palabras individuales como alternativa consulta

Si introduce su entrada de la muestra de búsqueda, Google y Bing sugieren lo siguiente:

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

Ver this exaple.

Escribir un raspador de pantalla pequeña para eso debería ser bastante fácil.

+0

http://stackoverflow.com/questions/3856630/how-to-separate-words-in-a-sentence-with-spaces - 8 líneas para un script de shell. –

0

para aquellos que necesitan una solución de expresiones regulares no

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; 
     }