2010-06-02 14 views
7

ho ottenuto il seguente:.Net Rimozione tutto il primo 0 di una stringa

01.05.03

ho bisogno di convertire che a 1.5.3

Il problema è che non posso solo tagliare il 0 perché se ho ottenuto:

01.05.10

ho bisogno di convertire che a 1.5.10

Quindi, qual è il modo migliore per risolvere questo problema? Regex? Se è così, qualsiasi esempio di regex che lo fa?

+0

Stai cercando di formattare una data? Ci sono modi migliori per farlo rispetto alla regex. – Oded

+2

No, non è una data, è un livello di gerarchia – Melursus

risposta

16

Ampliando la risposta di @FrustratedWithFormsDesigner:

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

+1 per Linq - se lo si può fare! Continuo a dimenticare che è possibile fare cose del genere. – FrustratedWithFormsDesigner

+1

+1 buona alternativa, sebbene non si occupi del caso "" 00.03.03 "' (che può verificarsi o meno). – Tomalak

+0

@Tomalak: questo è un buon punto. Lascia che ti aggiusti così :-) – dtb

3

È possibile split la stringa su ., quindi tagliare i primi 0 s sui risultati della divisione, quindi unirli di nuovo insieme.

Non conosco un modo per farlo in una singola operazione, ma è possibile scrivere una funzione che nasconde questo e lo rende look come una singola operazione. ;)

UPDATE:

Non ho nemmeno pensare di regex l'altro ragazzo. Sì, probabilmente lo farò in un'unica operazione.

+0

+1 per la facilità di lettura del codice risultante, piuttosto che un'espressione regolare che richiederebbe commenti –

+0

+1 Preferirei questo a una soluzione regex. – dtb

+0

@Miki Watts: Bene, la soluzione regex non richiede altri commenti rispetto alla variante split/loop/join: '/ * rimuove gli zeri iniziali sul numero di build * /'. – Tomalak

15

Regex-sostituire

(?<=^|\.)0+ 

con la stringa vuota. L'espressione regolare è:

 
(?<=  # 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 che non tutti i sapori regex supportano lunghezza variabile look-dietro, ma .NET fa.

Se ci si aspetta questo tipo di input: "00.03.03" e si desidera mantenere lo zero in questo caso (come "0.3.3"), usare questa espressione, invece:

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

e di nuovo sostituirlo con la stringa vuota.


Dai commenti (grazie Kobi): C'è un'espressione più concisa che non richiede look-dietro ed è equivalente al mio secondo suggerimento:

\b0+(?=\d) 

che è

 
\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 

Funziona perché il 0 sembra essere un carattere di parola, quindi i limiti di parola possono essere utilizzati per trovare il primo 0 in una riga. È un'espressione più compatibile, perché molti tipi di espressioni regex non supportano il look-behind a lunghezza variabile e alcuni (come JavaScript) non sembrano affatto indietro.

+0

Puoi darmi un esempio del codice C# che lo fa con la sostituzione, per favore? – Melursus

+4

@Melursus: No, perché questo * è * veramente facile * da trovare. La documentazione ufficiale e i siti web non contati (incluso Stack Overflow stesso) possono fornire un esempio su come utilizzare le espressioni regolari in .NET. – Tomalak

+1

'\ b0 + (? = \ D)' funzionerà bene qui e manterrà un singolo zero. – 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: è necessario verificare attentamente la combinazione di input possibile.

+1

Questo potrebbe non funzionare se avesse '001.00005.10', ma non ha specificato se sarebbe stato possibile. – FrustratedWithFormsDesigner

1

Ecco un altro modo che si possa fare ciò che FrustratedWithFormsDesigner suggerisce:

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

Questo è quasi la stessa risposta di DTB, ma doesn' t richiedono che le sottostringhe siano interi validi (funzionerebbe anche con, ad esempio, "000A.007.0HHIMARK").

UPDATE: Se ci si vuole tutte le stringhe composte da tutti 0 nella stringa di input da emettere come un unico 0, è possibile utilizzare questo:

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

ingresso Esempio/uscita:

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

Questa è la soluzione che avevo prima di cambiarla in "int.Parse". Fallisce quando una parte è composta interamente da caratteri "0", ad esempio "03.00.10". – dtb

+0

@dtb: cosa intendi per "fallire"? Non vedo dove l'OP abbia specificato cosa dovrebbe accadere in questo caso. Se gli zero finali devono essere rimossi, avrei pensato che l'output di "03.00.10" dovrebbe essere "03..10", che è. In caso contrario, l'OP dovrebbe fornire requisiti leggermente più dettagliati (a meno che manchi qualcosa). –

0

Questo sembra che sia un formato di data, in caso affermativo vorrei utilizzare codice per l'elaborazione

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

o meglio ancora

String newFormat = time.ToShortDateString(); 

che rispetterà voi e la vostra impostazione clienti cultura.

Se questi dati non è una data allora non utilizzare questo :)

+0

OP ha dichiarato che non è una data. – dtb

+0

scusate il commento. per OP –

1

C'è anche alla vecchia scuola che ha probabilmente caratteristiche delle prestazioni migliori rispetto maggior parte delle altre soluzioni menzionate. Qualcosa di simile:

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

ho avuto un requisito analogo per analizzare una stringa con indirizzi di strada, dove alcuni dei numeri civici avevano zeri e avevo bisogno di rimuoverli, mantenendo intatto il resto del testo, quindi ho un po ' modificato la risposta accettata per soddisfare le mie esigenze, forse qualcuno lo trova utile. Sostanzialmente si comporta come la risposta accettata, con la differenza che sto verificando se la parte di stringa può essere analizzata come un numero intero e in modo predefinito al valore di stringa quando 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); 
} 

ingresso: "Islands Brygge 34 B 07 TV"

in uscita: "Islands Brygge 34 B 7 TV"

Problemi correlati