2012-06-12 12 views
5

Per la rimozione di parte finale è io uso il codiceEsiste un modo migliore per rimuovere una parte finale della stringa in .NET?

str.substring(0,str.length -2) 

C'è un modo migliore? In particolare non mi piace usare str.length.

Edit ho voluto la questione di essere il più breve e semplice possibile e ho supposto che ho appena trascurato qualche metodo String. Cerco di essere più preciso.

Ho bisogno di rimuovere un determinato numero di caratteri dalla fine di una stringa. Non voglio preoccuparmi di quali sono i personaggi e non voglio introdurre il rischio di rimuovere più personaggi.

Se il numero è maggiore della lunghezza della stringa, è presente un'eccezione (la stringa deve essere convalidata in precedenza).

Non ho il problema in particolare con la lunghezza, ma con riferimento a una variabile due volte (immagina una funzione anziché una variabile). Inoltre non mi piace la necessità di sottrazione, ma è solo una preferenza personale.

VB.NET soution

La domanda è Taged vb.net per cui v'è un codice vb.net (dovrebbe essere in un modulo):

<System.Runtime.CompilerServices.Extension> _ 
Public Shared Function RemoveFromEnd(stringValue As String, removedCharacters As Integer) As String 
    Return stringValue.Substring(0, stringValue.Length - removedCharacters) 
End Function 
+1

cosa intendi per "parte finale"? – dtsg

+3

Per rimuovere gli ultimi x caratteri di una stringa è necessario conoscerne la lunghezza. Se semplicemente non ti piace vedere questo nel tuo codice, allora potresti scrivere un metodo di estensione per nascondere il calcolo. –

+0

@Duane: Intendo rimuovere gli ultimi x caratteri. – IvanH

risposta

8

Se la vostra preoccupazione è semplicemente l'estetica di ciò che si sta guardando, è banale per avvolgere questa funzionalità in un metodo di estensione:

public static string RemoveFromEnd(this string stringValue, int removedCharacters) 
    { 
     return stringValue.Substring(0, stringValue.Length - removedCharacters); 
    } 

Così si potrebbe quindi semplicemente utilizzare

str.RemoveFromEnd(2); 

e fatelo.

Se si è invece preoccupati delle prestazioni dell'utilizzo di string.length a causa della sua reputazione di lentezza nelle lingue non gestite, non esserlo. Poiché le stringhe in .Net sono immutabili, String.Length viene impostato quando la stringa viene dichiarata e non cambia mai. Pertanto, la referenza di String.Length termina nel tempo costante (ad es. Big-O (1)) ed è molto veloce. Al contrario, è necessario concentrarsi sulla chiamata Sottostringa se si è sensibili alle prestazioni. In .Net, la sottostringa completa in lineare tempo (ad es. Big-O (n)) dove n è la lunghezza della stringa originale. È quindi il collo di bottiglia delle prestazioni nella tua linea di codice. Diventerà più lento rispetto alla lunghezza della stringa.

Se si hanno a che fare con stringhe molto lunghe, tuttavia, potrebbe non essere corretto semplicemente ingerirlo. Per ovviare a qualcosa di simile si potrebbe utilizzare uno StringBuilder nel vostro metodo di estensione, invece:

public static string RemoveFromEnd(this string stringValue, int removedCharacters) 
    { 
     var newString = new StringBuilder(stringValue); 
     newString.Length = newString.Length - removedCharacters; 
     return newString.ToString(); 
    } 

Questo dovrebbe essere sempre costante, ma ho bisogno di controllare due volte Reflector per assicurarsi StringBuilder.Length si comporta il modo in cui penso che lo fa. Anche se è un tempo lineare, tuttavia, sarà lineare rispetto ai caratteri rimossi, che sarà necessariamente inferiore alla lunghezza della stringa originale. Il compromesso, ovviamente, è che si ha un po 'più di uso della memoria fino a quando lo StringBuilder non va oltre l'ambito, ma questo non dovrebbe essere un problema se lo si avvolge in un metodo di estensione che si completa molto rapidamente.

MODIFICA: Sì, StringBuilder.Length restituisce semplicemente String.Lunghezza della stringa di cui tiene traccia, in modo che ritorni in tempo costante e l'approccio StringBuilder al troncamento debba essere il più veloce possibile.

+0

Interessante. Pensavo che 'StringBulider.Length' fosse una proprietà get-only, ma vedo che sei corretto, è get/set. Aggiungerà molti caratteri ''\ 0'' se aumenti' Lunghezza'. Mi chiedo quando lo vorrai mai ... –

+0

@JeppeStigNielsen Quando ti stai preparando a scaricare un po 'di cose nel costruttore tutto frammentario e non vuoi che la cosa riallacci costantemente la struttura dati sottostante. Dovresti usare una variabile di indice e alcune altre cose che direi che sono generalmente troppo complicate e illeggibili per meritarmene la pena, ma se le prestazioni diventano una grande considerazione, dovresti semplicemente affidarti alla magia dei commenti. – tmesser

+0

Quando ho posto la domanda ero interessato all'estetica, ma apprezzo anche l'informazione sulla performance. Avete qualche stima della lunghezza per la quale è meglio usare StringBuilder? – IvanH

0

Dipende da cosa si intende per 'parte finale'. Intendi spazi bianchi dopo il contenuto? Quindi per esempio:

string test = "This is a test string. "; // But you want "This is a test string." 

e si desidera rimuovere gli spazi dopo? Ciò è possibile con i comandi .Trim() o .TrimEnd(). Se non intendi questo, per favore specifica quale sia il problema.

+0

Ho bisogno di rimuovere caratteri arbitrari (non solo spazi o caratteri specificati). – IvanH

+0

Questo non ha risposto alla domanda ma l'hai correttamente qualificato. Non meritavo un voto negativo. +1 per farti pari. – Paparazzi

+0

Grazie Blam. Immagino che sia abbastanza rischioso rispondere a domande poco chiare/vaghe. Ho davvero pensato che questa fosse la domanda più probabile. – pyrocumulus

0
 var test = " test"; 
     // Trim all trailing spaces 
     test = test.Trim(); 
     // Trim only starting trailing spaces 
     test = test.TrimStart(); 
     // Trim only ending trailing spaces 
     test = test.TrimEnd(); 


     var test = "abcTest"; 
     // Trim all trailing abc 
     var toRemove = new char[3]; 
     toRemove[0] = 'a'; 
     toRemove[1] = 'b'; 
     toRemove[2] = 'c'; 
     test = test.TrimStart(toRemove); 

Si dovrebbe utilizzare la funzione Trim() per rimuovere la parte finale

+0

Ho bisogno di rimuovere caratteri arbitrari (non solo spazi o caratteri specificati). – IvanH

+0

Trim, TrimStart e TrimEnd hanno sovraccarichi in cui è possibile passare un carattere [] con i caratteri arbitrari da rimuovere. Ecco la definizione: "La stringa che rimane dopo tutte le occorrenze di caratteri nel parametro trimChars viene rimossa dall'inizio della stringa corrente.Se trimChars è null o un array vuoto, i caratteri white-space vengono invece rimossi." http://msdn.microsoft.com/en-us/library/system.string.trimstart.aspx –

+1

"Caratteri arbitrari" significa che desidera rimuovere gli ultimi due caratteri, indipendentemente da cosa siano. La tua soluzione proposta richiederebbe che passi un 'char []' che contenga tutti i possibili caratteri - tutti 65.536 di essi. –

5

Partenza questa domanda correlata:

Trim string from the end of a string in .NET - why is this missing?

Poiché non c'è costruito nel metodo per fare questo, dovrai creare il tuo metodo (preferibilmente un metodo di estensione):

public static string RemoveCharsFromEnd(this string input, int charactersToRemove) 
{ 
    if (input.Length > charactersToRemove) 
     return input.substring(0, input.Length - charactersToRemove); 
    else 
     return ""; 
} 
+0

+1 per gestire il caso in cui è necessario rimuovere l'intera stringa. – MarkJ

+0

Questa risposta è buona ma la risposta accettata è più precisa. Apprezzo in particolare il collegamento con l'altra domanda (con risposta diversa accettata) che non ho trovato. – IvanH

3

Quindi non esiste un modo per rimuovere i primi 2 caratteri di stringa senza usare str.Length, vale a dire

str.Substring(2) 

e quindi vi chiedo come farlo dall'altra parte? Non penso che la struttura lo offra. È possibile utilizzare

str.Remove(str.Length - 2) 

ma che utilizza Length.

Ecco un modo brutto che utilizza LINQ e ha cattive prestazioni:

new string(str.Reverse().Skip(2).Reverse().ToArray()) 

Il brutto idea non gettare eccezioni quando la corda è troppo corta.

+0

La creatività è stata rifiutata qui :-) –

+0

Ha risposto alla domanda +1. Personalmente non vedo perché la questione sia stata votata, ma le risposte non sono state votate. – Paparazzi

+0

@ Blam Grazie. –

Problemi correlati