2008-11-27 1 views
58

¿Cuál es la mejor forma de convertir el caso Pascal (caso Camel superior) en una oración?La mejor manera de convertir el caso Pascal en una oración

Por ejemplo comenzando con

"AwaitingFeedback" 

y la conversión que a

"Awaiting feedback" 

C# preferible pero podría convertirla de Java o similar.

+1

El estuche Camel está a la espera de retroalimentación y no de espera retroalimentación (caso Pascal). Además, lo que quieres hacer no es completamente posible. ¿Qué hay de disableGPS? ¿Hay una solución lo suficientemente general como para manejar estos casos? – kgiannakakis

+0

@kgiannakakis alteró la pregunta en consecuencia. Siempre me olvido en qué dirección están los nombres, especialmente cuando hay Camel Camel superior e inferior. –

Respuesta

1

Pseudo-código:

NewString = ""; 
Loop through every char of the string (skip the first one) 
    If char is upper-case ('A'-'Z') 
    NewString = NewString + ' ' + lowercase(char) 
    Else 
    NewString = NewString + char 

mejores formas tal vez se puede hacer mediante el uso de expresiones regulares o mediante rutinas de sustitución de cadenas (reemplace 'X' con 'x')

2

que haría uso de una expresión regular, insertando un espacio antes de cada carácter en mayúscula y luego bajando toda la cuerda.

string spacedString = System.Text.RegularExpressions.Regex.Replace(yourString, "\B([A-Z])", " \k"); 
    spacedString = spacedString.ToLower(); 
+0

No sé C#, pero no creo que escapes como \ s sean legales en la sección de reemplazo: ¿cómo sabrá el idioma si debe insertar espacio, pestaña u otra cosa? :-) – PhiLho

+0

Tiene razón, debería ser más simple reemplazarlo por un "" claro. – Antoine

+0

Lo único que diría es que producirá "en espera de comentarios" –

15

Aquí tienes ...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace CamelCaseToString 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine(CamelCaseToString("ThisIsYourMasterCallingYou")); 
     } 

     private static string CamelCaseToString(string str) 
     { 
      if (str == null || str.Length == 0) 
       return null; 

      StringBuilder retVal = new StringBuilder(32); 

      retVal.Append(char.ToUpper(str[0])); 
      for (int i = 1; i < str.Length; i++) 
      { 
       if (char.IsLower(str[i])) 
       { 
        retVal.Append(str[i]); 
       } 
       else 
       { 
        retVal.Append(" "); 
        retVal.Append(char.ToLower(str[i])); 
       } 
      } 

      return retVal.ToString(); 
     } 
    } 
} 
+1

Deberías ToUpper() el primer personaje, de lo contrario tu rutina no funciona con camelCase verdadero, solo PascalCase –

+0

Siéntate atrapado, sabía que algo andaba mal (pero no pude entenderlo) cuando dijo "Esperando retroalimentación" es un estuche de camello! –

2

Es fácil de hacer en JavaScript (o PHP, etc.) donde se puede definir una función en la llamada reemplazar:

var camel = "AwaitingFeedbackDearMaster"; 
var sentence = camel.replace(/([A-Z].)/g, function (c) { return ' ' + c.toLowerCase(); }); 
alert(sentence); 

Aunque no he resuelto el problema de la tapa inicial ... :-)

Ahora, para la solución de Java:

String ToSentence(String camel) 
{ 
    if (camel == null) return ""; // Or null... 
    String[] words = camel.split("(?=[A-Z])"); 
    if (words == null) return ""; 
    if (words.length == 1) return words[0]; 
    StringBuilder sentence = new StringBuilder(camel.length()); 
    if (words[0].length() > 0) // Just in case of camelCase instead of CamelCase 
    { 
    sentence.append(words[0] + " " + words[1].toLowerCase()); 
    } 
    else 
    { 
    sentence.append(words[1]); 
    } 
    for (int i = 2; i < words.length; i++) 
    { 
    sentence.append(" " + words[i].toLowerCase()); 
    } 
    return sentence.toString(); 
} 

System.out.println(ToSentence("AwaitingAFeedbackDearMaster")); 
System.out.println(ToSentence(null)); 
System.out.println(ToSentence("")); 
System.out.println(ToSentence("A")); 
System.out.println(ToSentence("Aaagh!")); 
System.out.println(ToSentence("stackoverflow")); 
System.out.println(ToSentence("disableGPS")); 
System.out.println(ToSentence("Ahh89Boo")); 
System.out.println(ToSentence("ABC")); 

Nota el truco para dividir la frase sin perder el carácter ...

4

Aquí está una manera básica de hacer lo que me ocurrió con el uso de expresiones regulares

public static string CamelCaseToSentence(this string value) 
{ 
    var sb = new StringBuilder(); 
    var firstWord = true; 

    foreach (var match in Regex.Matches(value, "([A-Z][a-z]+)|[0-9]+")) 
    { 
     if (firstWord) 
     { 
      sb.Append(match.ToString()); 
      firstWord = false; 
     } 
     else 
     { 
      sb.Append(" "); 
      sb.Append(match.ToString().ToLower()); 
     } 
    } 

    return sb.ToString(); 
} 

También será escindido números que no especifiqué pero serían útiles.

2
string camel = "MyCamelCaseString"; 
string s = Regex.Replace(camel, "([A-Z])", " $1").ToLower().Trim(); 
Console.WriteLine(s.Substring(0,1).ToUpper() + s.Substring(1)); 

Editar: no notó los requisitos de su carcasa, modificada en consecuencia. Podría usar un matchevaluator para hacer la carcasa, pero creo que una subcadena es más fácil.También podría envolverlo en una segunda expresión regular sustituir, donde puede cambiar el primer carácter

"^\w" 

a superior

\U (i think) 
0

Parcialmente already answered here

Pequeño chage a la respuesta aceptada, para convertir el segundo y letras mayúsculas en minúscula para minúsculas, así que cambie

if (char.IsUpper(text[i]))     
    newText.Append(' ');    
newText.Append(text[i]); 

a

if (char.IsUpper(text[i]))     
{ 
    newText.Append(' ');    
    newText.Append(char.ToLower(text[i])); 
} 
else 
    newText.Append(text[i]); 
59
public static string ToSentenceCase(this string str) 
{ 
    return Regex.Replace(str, "[a-z][A-Z]", m => m.Value[0] + " " + char.ToLower(m.Value[1])); 
} 

En las versiones de Visual Studio después de 2015, se puede hacer

public static string ToSentenceCase(this string str) 
{ 
    return Regex.Replace(str, "[a-z][A-Z]", m => $"{m.Value[0]} {char.ToLower(m.Value[1])}"); 
} 

Basado en: Converting Pascal case to sentences using regular expression

1

Una solución xquery que funcione para ambos casos UpperCamel y lowerCamel:

Para el caso de sentencia de salida (solo el primer carácter de la primera palabra es c apitalized):

declare function content:sentenceCase($string) 
{ 
let $firstCharacter := substring($string, 1, 1) 
let $remainingCharacters := substring-after($string, $firstCharacter) 
return 
concat(upper-case($firstCharacter),lower-case(replace($remainingCharacters, '([A-Z])', ' $1'))) 
}; 

Para el caso del título de salida (primer carácter de cada palabra en mayúsculas):

declare function content:titleCase($string) 
{ 
let $firstCharacter := substring($string, 1, 1) 
let $remainingCharacters := substring-after($string, $firstCharacter) 
return 
concat(upper-case($firstCharacter),replace($remainingCharacters, '([A-Z])', ' $1')) 
}; 
13

Esto funciona para mí:

Regex.Replace(strIn, "([A-Z]{1,2}|[0-9]+)", " $1").TrimStart() 
+4

¿Cómo cambia esto el caso de la letra después del espacio? –

+0

Esto puede no devolver lo que intenta para casos como 'AwaitingTFeedback' o' Awaiting9Feedback'. [La respuesta de Jef] (https://stackoverflow.com/a/11432809/661933) es mejor para mí (que devuelve 'Awaiting T Feedback' y' Awaiting9 Feedback' respectivamente). – nawfal

4

Esto es igual que @ SSTA, pero es más eficiente que llamar a TrimStart.

Regex.Replace("ThisIsMyCapsDelimitedString", "(\\B[A-Z])", " $1") 
6

encontrado esto en la fuente MvcContrib, no parece ser mencionado aquí todavía.

return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim(); 
0

Me encontré haciendo algo similar, y agradezco tener un punto de partida en esta discusión. Esta es mi solución, colocada como un método de extensión para la clase de cadena en el contexto de una aplicación de consola.

using System; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string piratese = "avastTharMatey"; 
      string ivyese = "CheerioPipPip"; 

      Console.WriteLine("{0}\n{1}\n", piratese.CamelCaseToString(), ivyese.CamelCaseToString()); 
      Console.WriteLine("For Pete\'s sake, man, hit ENTER!"); 
      string strExit = Console.ReadLine(); 
     } 

    } 

    public static class StringExtension 
    { 
     public static string CamelCaseToString(this string str) 
     { 
      StringBuilder retVal = new StringBuilder(32); 

      if (!string.IsNullOrEmpty(str)) 
      { 
       string strTrimmed = str.Trim(); 

       if (!string.IsNullOrEmpty(strTrimmed)) 
       { 
        retVal.Append(char.ToUpper(strTrimmed[0])); 

        if (strTrimmed.Length > 1) 
        { 
         for (int i = 1; i < strTrimmed.Length; i++) 
         { 
          if (char.IsUpper(strTrimmed[i])) retVal.Append(" "); 

          retVal.Append(char.ToLower(strTrimmed[i])); 
         } 
        } 
       } 
      } 
      return retVal.ToString(); 
     } 
    } 
} 
6

Preferiré usar Humanizer para esto. Humanizer es una biblioteca de clases portátil que satisface todas sus necesidades de .NET para manipular y mostrar cadenas, enumeraciones, fechas, horas, intervalos de tiempo, números y cantidades.

Respuesta corta

"AwaitingFeedback".Humanize() => Awaiting feedback 

largo y respuesta descriptiva

Humanizer puede hacer mucho más trabajo Otros ejemplos son:

"PascalCaseInputStringIsTurnedIntoSentence".Humanize() => "Pascal case input string is turned into sentence" 
"Underscored_input_string_is_turned_into_sentence".Humanize() => "Underscored input string is turned into sentence" 
"Can_return_title_Case".Humanize(LetterCasing.Title) => "Can Return Title Case" 
"CanReturnLowerCase".Humanize(LetterCasing.LowerCase) => "can return lower case" 

de código completo es:

using Humanizer; 
using static System.Console; 

namespace HumanizerConsoleApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      WriteLine("AwaitingFeedback".Humanize()); 
      WriteLine("PascalCaseInputStringIsTurnedIntoSentence".Humanize()); 
      WriteLine("Underscored_input_string_is_turned_into_sentence".Humanize()); 
      WriteLine("Can_return_title_Case".Humanize(LetterCasing.Title)); 
      WriteLine("CanReturnLowerCase".Humanize(LetterCasing.LowerCase)); 
     } 
    } 
} 

salida

espera de retroalimentación

cadena de entrada caso Pascal es convertido en frase

cadena de entrada expresiones subrayadas se convirtió en frase puede devolver Título Caso

puede volver más baja estuche

Si prefiere escribir su propio código C#, puede lograrlo escribiendo algunas cosas del código C# como ya han respondido otros.

Cuestiones relacionadas