Pregunta

Estoy escribiendo un código que necesita hacer la normalización de la cadena, quiero convertir una cadena dada en una representación de caso de camello (bueno, al menos en la mejor estimación). Ejemplo:

"the quick brown fox" => "TheQuickBrownFox"
"the_quick_brown_fox" => "TheQuickBrownFox"
"123The_quIck bROWN FOX" => "TheQuickBrownFox"
"the_quick brown fox 123" => "TheQuickBrownFox123"
"thequickbrownfox" => "Thequickbrownfox"

Creo que deberías poder obtener la idea de esos ejemplos. Quiero eliminar todos los caracteres especiales (', " ;,!, ??@,., Etc.), poner en mayúscula cada palabra (las palabras están definidas por un espacio, _ o -) y cualquier los números iniciales se eliminaron (arrastrar / interno están bien, pero este requisito no es vital, dependiendo de la dificultad).

Estoy tratando de averiguar cuál sería la mejor manera de lograr esto. Mi primera suposición sería con una expresión regular, pero mis habilidades de expresión regular son malas en el mejor de los casos, por lo que realmente no sabría por dónde empezar.

Mi otra idea sería hacer un bucle y analizar los datos, digamos dividirlos en palabras , analizar cada uno y reconstruir la cadena de esa manera.

¿O hay otra forma en la que podría hacerlo?

¿Fue útil?

Solución

¿Qué tal una solución simple que utilice Strings.StrConv en el espacio de nombres Microsoft.VisualBasic? (No olvide agregar una referencia de proyecto a Microsoft.VisualBasic):

using System;
using VB = Microsoft.VisualBasic;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(VB.Strings.StrConv("QUICK BROWN", VB.VbStrConv.ProperCase, 0));
            Console.ReadLine();
        }
    }
}

Otros consejos

Esta expresión regular coincide con todas las palabras. Luego, los Agregamos con un método que pone en mayúscula los primeros caracteres, y ToLower es el resto de la cadena.

Regex regex = new Regex(@"[a-zA-Z]*", RegexOptions.Compiled);

private string CamelCase(string str)
{
    return regex.Matches(str).OfType<Match>().Aggregate("", (s, match) => s + CamelWord(match.Value));
}

private string CamelWord(string word)
{
    if (string.IsNullOrEmpty(word))
        return "";

    return char.ToUpper(word[0]) + word.Substring(1).ToLower();
}

Este método ignora los números, por cierto. Para agregarlos, puede cambiar la expresión regular a @ " [a-zA-Z] * | [0-9] * " , supongo, pero no lo he probado.

Cualquier solución que involucre la coincidencia de caracteres particulares puede no funcionar bien con algunas codificaciones de caracteres, especialmente si se usa la representación Unicode, que tiene docenas de caracteres espaciales, miles de 'símbolos', miles de caracteres de puntuación, miles de 'letras' , etc. Siempre que sea posible, sería mejor utilizar funciones compatibles con Unicode incorporadas. En términos de lo que es un 'carácter especial', bien podría decidir en función de Unicode categorías . Por ejemplo, incluiría 'Puntuación' pero incluiría 'Símbolos'?

ToLower (), IsLetter (), etc. debería estar bien, y tener en cuenta todas las letras posibles en Unicode. La comparación entre guiones y barras diagonales probablemente debería tener en cuenta algunas de las docenas de espacios y caracteres de guiones en Unicode.

Podría usar zapatillas ruby ??para trabajar :)

def camelize str
  str.gsub(/^[^a-zA-z]*/, '').split(/[^a-zA-Z0-9]/).map(&:capitalize).join
end

pensé que sería divertido probarlo, esto es lo que se me ocurrió:

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

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();
            string sentence = "123The_quIck bROWN FOX1234";

            sentence = sentence.ToLower();

            char[] s = sentence.ToCharArray();

            bool atStart = true;
            char pChar = ' ';

            char[] spaces = { ' ', '_', '-' };
            char a;
            foreach (char c in s)
            {
                if (atStart && char.IsDigit(c)) continue;

                if (char.IsLetter(c))
                {
                    a = c;
                    if (spaces.Contains(pChar))
                        a = char.ToUpper(a);
                    sb.Append(a);
                    atStart = false;
                }
                else if(char.IsDigit(c))
                {
                    sb.Append(c);
                }
                pChar = c;
            }

            Console.WriteLine(sb.ToString());
            Console.ReadLine();
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top