Come rimuovo tutti i caratteri non alfanumerici da una stringa tranne il trattino?


606

Come rimuovo tutti i caratteri non alfanumerici da una stringa tranne i caratteri trattino e spazio?

Risposte:


870

Sostituisci [^a-zA-Z0-9 -]con una stringa vuota.

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
str = rgx.Replace(str, "");

79
Vale la pena ricordare che -deve essere alla fine della classe di personaggi, o evaso con una barra rovesciata, per evitare di essere usato per un intervallo.
Peter Boughton,

6
@Dan imposta la bandiera globale nella tua regex - senza di essa, sostituisce solo la prima partita. Un rapido google dovrebbe dirti come impostare il flag globale nella regex ASP classica. Altrimenti, cerca una replaceAllfunzione anziché replace.
Amarghosh,

20
Ecco una versione compilata regex: return Regex.Replace(str, "[^a-zA-Z0-9_.]+", "", RegexOptions.Compiled); stessa domanda di base
Paige Watson,

13
@MGOwen perché ogni volta che usi "" stai creando un nuovo oggetto perché le stringhe sono immutabili. Quando usi string.empty stai riutilizzando la singola istanza richiesta per rappresentare una stringa vuota che è più veloce oltre che più efficiente.
Brian Scott,

17
@BrianScott So che questo è vecchio, ma è stato trovato in una ricerca, quindi ritengo che sia rilevante. Questo in realtà dipende dalla versione di .NET in esecuzione. > 2.0 utilizza ""e string.Emptyesattamente lo stesso. stackoverflow.com/questions/151472/…
Jared il

348

Avrei potuto usare RegEx, possono fornire una soluzione elegante ma possono causare problemi di performane. Ecco una soluzione

char[] arr = str.ToCharArray();

arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c) 
                                  || char.IsWhiteSpace(c) 
                                  || c == '-')));
str = new string(arr);

Quando si utilizza il framework compatto (che non ha FindAll)

Sostituisci FindAll con 1

char[] arr = str.Where(c => (char.IsLetterOrDigit(c) || 
                             char.IsWhiteSpace(c) || 
                             c == '-')).ToArray(); 

str = new string(arr);

1 commento di ShawnFeatherly


41
nei miei test, questa tecnica è stata molto più veloce. per essere precisi, era poco meno di 3 volte più veloce della tecnica Regex Replace.
Dan,

12
Il framework compatto non ha FindAll, è possibile sostituire FindAll conchar[] arr = str.Where(c => (char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-')).ToArray();
ShawnFeatherly

2
qualcuno l'ha provato? Non ha funzionato affatto. - ma questo ha fatto per me: string str2 = new string (str.Where (c => (char.IsLetterOrDigit (c))). ToArray ());
KevinDeus,

48

Puoi provare:

string s1 = Regex.Replace(s, "[^A-Za-z0-9 -]", "");

Dov'è la stua stringa.


1
OP ha chiesto trattino non sottolineato
Sean B

39

Utilizzando System.Linq

string withOutSpecialCharacters = new string(stringWithSpecialCharacters.Where(c =>char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-').ToArray());

@Michael È simile ma almeno questo è un liner, piuttosto che 3 righe. Direi che è abbastanza per renderlo una risposta diversa.
Dymas,

1
@Dymas Ora concordo sul fatto che sia accettabile, ma non perché lo spazio bianco è diverso. Apparentemente la parte funzionalmente equivalente (solo i nomi delle varianti differiscono) è stata modificata dopo che questa risposta è stata scritta.
Michael - Dov'è Clay Shirky il

1
@ZainAli, se fai una modifica banale e mi fai il ping, invertirò il mio downvote. Mi scuso per qualsiasi insinuazione della plagio.
Michael - Dov'è Clay Shirky il

22

Il regex è [^\w\s\-]*:

\sè meglio usare al posto dello spazio ( ), perché potrebbe esserci una scheda nel testo.


1
a meno che tu non voglia rimuovere le schede.
Matt Ellen,

... e newline, e tutti gli altri personaggi considerati "spazi bianchi".
Peter Boughton,

6
Questa soluzione è di gran lunga superiore alle soluzioni di cui sopra poiché supporta anche caratteri internazionali (non inglesi). <! - language: c # -> string s = "Mötley Crue 日本人: の 氏 名 e Kanji 愛 e Hiragana あ い"; string r = Regex.Replace (s, "[^ \\ w \\ s -] *", ""); Quanto sopra produce r con: Mötley Crue 日本人 の 氏 名 e Kanji 愛 e Hiragana あ い
danglund

1
Usa @ per uscire da \ conversione in stringa: @ "[^ \ w \ s -] *"
Jakub Pawlinski

1
uhhh ... non rimuove i trattini bassi? che è considerato un carattere "parola" dall'implementazione di regex nella creazione, ma non è alfanumerico, trattino o spazio ... (?)
Codice Jockey

14

Sulla base della risposta a questa domanda, ho creato una classe statica e le ho aggiunte. Ho pensato che potesse essere utile per alcune persone.

public static class RegexConvert
{
    public static string ToAlphaNumericOnly(this string input)
    {
        Regex rgx = new Regex("[^a-zA-Z0-9]");
        return rgx.Replace(input, "");
    }

    public static string ToAlphaOnly(this string input)
    {
        Regex rgx = new Regex("[^a-zA-Z]");
        return rgx.Replace(input, "");
    }

    public static string ToNumericOnly(this string input)
    {
        Regex rgx = new Regex("[^0-9]");
        return rgx.Replace(input, "");
    }
}

Quindi i metodi possono essere usati come:

string example = "asdf1234!@#$";
string alphanumeric = example.ToAlphaNumericOnly();
string alpha = example.ToAlphaOnly();
string numeric = example.ToNumericOnly();

2
Per l'esempio fornito, sarebbe utile anche se si forniscono i risultati di ciascuno dei metodi.
C-Chavez,

7

Vuoi qualcosa di veloce?

public static class StringExtensions 
{
    public static string ToAlphaNumeric(this string self, params char[] allowedCharacters)
    {
        return new string(Array.FindAll(self.ToCharArray(), c => char.IsLetterOrDigit(c) || allowedCharacters.Contains(c)));
    }
}

Ciò ti consentirà di specificare anche quali caratteri vuoi consentire.


5

Ecco una soluzione rapida per l'allocazione di heap non regex che era quello che stavo cercando.

Edizione non sicura.

public static unsafe void ToAlphaNumeric(ref string input)
{
    fixed (char* p = input)
    {
        int offset = 0;
        for (int i = 0; i < input.Length; i++)
        {
            if (char.IsLetterOrDigit(p[i]))
            {
                p[offset] = input[i];
                offset++;
            }
        }
        ((int*)p)[-1] = offset; // Changes the length of the string
        p[offset] = '\0';
    }
}

E per coloro che non vogliono usare non sicuri o non si fidano dell'hack della lunghezza della stringa.

public static string ToAlphaNumeric(string input)
{
    int j = 0;
    char[] newCharArr = new char[input.Length];

    for (int i = 0; i < input.Length; i++)
    {
        if (char.IsLetterOrDigit(input[i]))
        {
            newCharArr[j] = input[i];
            j++;
        }
    }

    Array.Resize(ref newCharArr, j);

    return new string(newCharArr);
}

4

Ho fatto una soluzione diversa, eliminando i personaggi di controllo , che era il mio problema originale.

È meglio che mettere in una lista tutti i caratteri "speciali ma buoni"

char[] arr = str.Where(c => !char.IsControl(c)).ToArray();    
str = new string(arr);

è più semplice, quindi penso che sia meglio!


2

Ecco un metodo di estensione che utilizza @ata answer come ispirazione.

"hello-world123, 456".MakeAlphaNumeric(new char[]{'-'});// yields "hello-world123456"

o se hai bisogno di caratteri aggiuntivi diversi dal trattino ...

"hello-world123, 456!?".MakeAlphaNumeric(new char[]{'-','!'});// yields "hello-world123456!"


public static class StringExtensions
{   
    public static string MakeAlphaNumeric(this string input, params char[] exceptions)
    {
        var charArray = input.ToCharArray();
        var alphaNumeric = Array.FindAll<char>(charArray, (c => char.IsLetterOrDigit(c)|| exceptions?.Contains(c) == true));
        return new string(alphaNumeric);
    }
}

1

Uso una variante di una delle risposte qui. Voglio sostituire gli spazi con "-" in modo che sia SEO friendly e anche in minuscolo. Inoltre, non fare riferimento a system.web dal mio livello di servizi.

private string MakeUrlString(string input)
{
    var array = input.ToCharArray();

    array = Array.FindAll<char>(array, c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c) || c == '-');

    var newString = new string(array).Replace(" ", "-").ToLower();
    return newString;
}

0

Ecco una versione molto concisa

myString = myString.replace(/[^A-Za-z0-9 -]/g, "");

-1

C'è un modo molto più semplice con Regex.

private string FixString(string str)
{
    return string.IsNullOrEmpty(str) ? str : Regex.Replace(str, "[\\D]", "");
}

1
sostituisce solo caratteri non numerici
frostymarvelous,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.