2010-06-02 5 views
7

me dio la siguiente:.Net La eliminación de toda la primera 0 de una cadena

01.05.03

Necesito convertir que a 1.5.3

El problema es que no sólo se puede recortar el 0 porque si llegué:

01.05.10

necesito convertir que a 1.5.10

Entonces, ¿cuál es la mejor manera de resolver ese problema? Regex? Si es así, ¿algún ejemplo de expresiones regulares que hace eso?

+0

¿Estás tratando de dar formato a una fecha? Hay mejores formas de hacer esto que regex. – Oded

+2

No, no es una fecha, es un nivel de jerarquía – Melursus

Respuesta

16

Ampliando la respuesta de @FrustratedWithFormsDesigner:

string Strip0s(string s) 
{ 
    return string.Join<int>(".", from x in s.Split('.') select int.Parse(x)); 
} 
+1

+1 para Linq-ifying it! Me olvido de que es posible hacer cosas como esa. – FrustratedWithFormsDesigner

+1

+1 buena alternativa, aunque no trata el caso '' 00.03.03 '' (que puede ocurrir o no). – Tomalak

+0

@Tomalak: ese es un buen punto. Déjame arreglar eso :-) – dtb

3

Puede split la secuencia en ., luego recortar los 0 primeros en los resultados de la división, luego combinarlos nuevamente.

No sé de una manera de hacer esto en una sola operación, pero podría escribir una función que lo oculte y lo haga mirar como una sola operación. ;)

ACTUALIZACIÓN:

Ni siquiera pienso en expresiones regulares de la otra persona. Sí, eso probablemente lo hará en una sola operación.

+0

+1 para facilitar la lectura del código resultante, en lugar de una expresión regular que requeriría comentarios –

+0

+1 Preferiría esto a una solución de expresiones regulares. – dtb

+0

@Miki Watts: Bueno, la solución de expresiones regulares no requiere más comentarios que la variante de split/loop/join: '/ * elimina los ceros a la izquierda en el número de compilación * /'. – Tomalak

15

Regex reemplazar

(?<=^|\.)0+ 

con la cadena vacía. La expresión regular es:

 
(?<=  # begin positive look-behind (i.e. "a position preceded by") 
    ^|\. # the start of the string or a literal dot † 
)  # end positive look-behind 
0+  # one or more "0" characters 

† nota que no todos los sabores de expresiones regulares compatibles con longitud variable de observación detrás, pero .NET hace.

Si esperas este tipo de entrada: "00.03.03" y desea mantener el cero en este caso (como "0.3.3"), utilice esta expresión en su lugar:

(?<=^|\.)0+(?=\d) 

y otra vez reemplace con la cadena vacía.


De los comentarios (gracias Kobi): No es una expresión más concisa que no requiere de observación detrás y es equivalente a mi segunda sugerencia:

\b0+(?=\d) 

que es

 
\b  # a word boundary (a position between a word char and a non-word char) 
0+  # one or more "0" characters 
(?=\d) # positive look-ahead: a position that's followed by a digit 

Esto funciona porque el 0 pasa a ser un carácter de palabra, por lo que los límites de las palabras se pueden utilizar para encontrar el primer 0 en una fila. Es una expresión más compatible, ya que muchos sabores de expresiones regulares no son compatibles con la apariencia de longitud variable detrás, y algunos (como JavaScript) no buscan en absoluto.

+0

¿Puede darme un ejemplo del código C# que hace eso con el reemplazo por favor? – Melursus

+4

@Melursus: No, porque es * realmente fácil * de encontrar. La documentación oficial y los sitios web no incluidos (incluido Stack Overflow en sí) pueden darle un ejemplo de cómo usar expresiones regulares en .NET. – Tomalak

+1

'\ b0 + (? = \ D)' también funcionará muy bien aquí, y mantendrá un solo cero. – Kobi

0
string s = "01.05.10"; 
string newS = s.Replace(".0", "."); 
newS = newS.StartsWith("0") ? newS.Substring(1, newS.Length - 1) : newS; 

Console.WriteLine(newS); 

NOTA: Deberá comprobar minuciosamente la posible combinación de entradas.

+1

Esto podría no funcionar si tenía '001.00005.10', pero no especificó si eso sería posible. – FrustratedWithFormsDesigner

1

Ésta es otra manera se podría hacer lo FrustratedWithFormsDesigner sugiere:

string s = "01.05.10"; 
string s2 = string.Join(
    ".", 
    s.Split('.') 
     .Select(str => str.TrimStart('0')) 
     .ToArray() 
); 

Ésta es casi la misma que la respuesta de DTB, pero doesn' t requiere que las subcadenas sean enteros válidos (también funcionaría con, por ejemplo, "000A.007.0HHIMARK").

ACTUALIZACIÓN: Si usted querría cualquier cadena que consta de todos los 0s en la cadena de entrada a enviar como un solo 0, se puede usar esto:

string s2 = string.Join(
    ".", 
    s.Split('.') 
     .Select(str => TrimLeadingZeros(str)) 
     .ToArray() 
); 

public static string TrimLeadingZeros(string text) { 
    int number; 
    if (int.TryParse(text, out number)) 
     return number.ToString(); 
    else 
     return text.TrimStart('0'); 
} 

Ejemplo de entrada/salida:

00.00.000A.007.0HHIMARK // input 
0.0.A.7.HHIMARK   // output 
+0

Esa es la solución que tenía antes de cambiarla a 'int.Parse'. Falla cuando una parte se compone completamente de caracteres '' 0'', por ejemplo, '' 03.00.10 "'. – dtb

+0

@dtb: ¿Qué quiere decir con "falla"? No veo dónde el OP especificó lo que debería suceder en este caso. Si se van a eliminar los ceros al final, hubiera pensado que la salida de "03.00.10" debería ser "03..10", que es. De lo contrario, el PO necesitaría proporcionar requisitos un poco más detallados (a menos que me falta algo). –

0

Esto parece que es un formato de fecha, de ser así me gustaría utilizar el código de procesamiento fecha

DateTime time = DateTime.Parse("01.02.03"); 
String newFormat = time.ToString("d.M.yy"); 

o incluso mejor

String newFormat = time.ToShortDateString(); 

que respete usted y su entorno clientes cultura.

Si estos datos no es una fecha entonces no utilice esta :)

+0

OP declaró que no es una fecha. – dtb

+0

, perdí el comentario. por OP –

1

Hay también la manera de la vieja escuela que probablemente tiene mejores características de rendimiento que la mayoría de otras soluciones mencionadas. Algo así como:

static public string NormalizeVersionString(string versionString) 
{ 
    if(versionString == null) 
     throw new NullArgumentException("versionString"); 

    bool insideNumber = false;  
    StringBuilder sb = new StringBuilder(versionString.Length); 
    foreach(char c in versionString) 
    { 
     if(c == '.') 
     { 
      sb.Append('.'); 
      insideNumber = false; 
     } 
     else if(c >= '1' && c <= '9') 
     { 
      sb.Append(c); 
      insideNumber = true; 
     } 
     else if(c == '0') 
     { 
      if(insideNumber) 
       sb.Append('0'); 
     } 
    } 
    return sb.ToString(); 
} 
0

que tenía un requisito similar para analizar una cadena con direcciones de calles, donde algunos de los números de las casas habían ceros a la izquierda y que necesitaba para borrarlas, manteniendo el resto del texto se mantengan intactos, así que un poco edité la respuesta aceptada para cumplir con mis requisitos, tal vez alguien lo encuentre útil. Básicamente haciendo lo mismo que la respuesta aceptada, con la diferencia de que estoy comprobando si la parte de la cadena se puede analizar como un entero, y el valor de la cadena por defecto es falso;

string Strip0s(string s) 
{ 
    int outputValue; 
    return 
     string.Join(" ", 
      from x in s.Split(new[] { ' ' }) 
      select int.TryParse(x, out outputValue) ? outputValue.ToString() : x); 
} 

de entrada: "Islas Brygge 34 B 07 TV"

salida: "Islas Brygge 34 B 7 TV"

Cuestiones relacionadas