2010-05-20 18 views
5

Tengo una pregunta muy simple, y no debería dejar de hablar de esto, pero lo estoy. ¡Jaja!¿Cuál es la forma más eficiente de formatear la siguiente cadena?

que tienen una cadena que recibo en el siguiente formato (s):

123456-D53

123455-4D

234234-4

La salida deseada, formato posterior, es:

123-455-444

123-455-55

123-455-5

o

123-455

El formato depende en última instancia de la número total de caracteres en la cadena original ..

Tengo seve Ideas ral de cómo hacer esto, pero sigo lo que hay una manera mejor que String.Replace y concatenar ...

, gracias por las sugerencias ..

Ian

+6

¿Seguro que la eficiencia es la métrica más importante aquí y no, por ejemplo, la legibilidad? ¿Ha perfilado para ver si este es el cuello de botella en su programa? –

+1

No en ambas cuentas. De hecho, estoy seguro de que no es un cuello de botella y que la eficiencia no es la métrica más importante. Solo tengo curiosidad y lo he estado pensando todo el día. :) –

Respuesta

2

Supongo que esto no solo depende de que las entradas sean siempre numéricas. Si es así, estoy pensando en algo como esto

private string ApplyCustomFormat(string input) 
{ 
    StringBuilder builder = new StringBuilder(input.Replace("-", "")); 

    int index = 3; 
    while (index < builder.Length) 
    { 
     builder.Insert(index, "-"); 
     index += 4; 
    } 
    return builder.ToString(); 
} 
+0

Esto es similar a mi implementación. Estoy atrapado en el "¿Es esta la forma más eficiente de hacer esto?" pregunta .. –

+0

@Ian P - "más eficiente" es menos importante que "lo suficientemente eficiente". Ver el primer comentario. Me sentiría tentado a escribir código "menos eficiente" que utiliza un chunker IEnumerable (método o Regex) y String.Join ;-) –

+0

Escogió este como la respuesta, ya que funcionó primero según la especificación que describo. Aunque, los otros carteles actualizaron su código para que funcione como se requiere. Todos son dignos de marcas verdes, pero solo puedo dar uno :) –

2

EDIT: Ver la historia de versiones antiguas.
Puede buscar char.IsDigit() solo para encontrar los dígitos.

var output = new StringBuilder(); 
var digitCount = 0; 

foreach(var c in input) 
{ 
    if(char.IsDigit(c)) 
    { 
    output.Append(c); 
    digitCount++; 
    if(digitCount % 3 == 0) 
    { 
     output.Append("-"); 
    } 
    } 
} 

// Remove possible last - 
return output.ToString().TrimEnd('-'); 

Este código debe llenar de izquierda a derecha (ahora lo tengo, primera lectura, a continuación, el código) ...
Lo sentimos, todavía no se puede probar esto ahora.

+0

Estoy a punto de aclarar mi publicación original, la cadena puede ser alfanumérica, no solo numérica. –

+0

Creo que esto llena los números en la dirección incorrecta. Él lo quiere Justificado a la izquierda, por así decirlo. – user7116

+0

@Ian: uso char.IsDigit, ahora. @sixlettervariables: tienes razón, eso lo hace mucho más difícil. – tanascius

4

Tanascius es correcto, pero no puedo comentar o Upvote debido a mi falta de representante, pero si desea información adicional sobre la string.format he encontrado útil esta información. http://blog.stevex.net/string-formatting-in-csharp/

+0

Excelente enlace, gracias. –

+0

Debería haberte hecho saber que borré mi respuesta :-). El OP cambió la pregunta y ya no se aplica. Además, sixlettervariable señaló que en realidad no responde la pregunta original también. –

0
No

el más rápido, pero fácil en los ojos (ed: leer):

string Normalize(string value) 
{ 
    if (String.IsNullOrEmpty(value)) return value; 

    int appended = 0; 
    var builder = new StringBuilder(value.Length + value.Length/3); 
    for (int ii = 0; ii < value.Length; ++ii) 
    { 
     if (Char.IsLetterOrDigit(value[ii])) 
     { 
      builder.Append(value[ii]); 
      if ((++appended % 3) == 0) builder.Append('-'); 
     } 
    } 

    return builder.ToString().TrimEnd('-'); 
} 

Utiliza una conjetura reservar previamente la longitud del StringBuilder 's. Esto aceptará cualquier entrada alfanumérica con cualquier cantidad de basura que agregue el usuario, incluido el espacio en blanco en exceso.

+6

Jaja, debemos tener diferentes tipos de ojos: p –

+0

Debería comprobar por '(ii + 1)% 3 == 0'. –

+0

@ 0xA3: buena captura. @pst: si vuelvo para leer esto, será obvio lo que está pasando. Sin ofuscación;) – user7116

2

Aquí hay un método que usa una combinación de expresiones regulares y LINQ para extraer grupos de tres letras a la vez y luego los une de nuevo. Nota: asume que la entrada ya ha sido validada.La validación también se puede hacer con una expresión regular.

string s = "123456-D53"; 
string[] groups = Regex.Matches(s, @"\w{1,3}") 
         .Cast<Match>() 
         .Select(match => match.Value) 
         .ToArray(); 
string result = string.Join("-", groups); 

Resultado:

 
123-456-D53 
Cuestiones relacionadas