Come si possono eliminare caratteri non ASCII da una stringa? (in C#)


180

Come si possono eliminare caratteri non ASCII da una stringa? (In C#)

+3

Per la risposta di sinelaw [sotto] (http://stackoverflow.com/a/10036919/298754), se invece desidera sostituire i caratteri * * non ASCII, ** vedi [questa risposta] (http: // stackoverflow.com/a/10036907/562906) invece **. 10 dic. 132013-12-10 15:37:13

355
string s = "søme string"; 
s = Regex.Replace(s, @"[^\u0000-\u007F]+", string.Empty); 
+14

Per quelli di noi con la RegEx sfidati, ti dispiacerebbe scrivere in inglese il tuo modello RegEx. In altre parole, "il^fa questo", ecc ... 23 set. 082008-09-23 22:45:15

+42

@Metro Smurf il^è l'operatore non. Indica alla regex di trovare tutto ciò che non corrisponde, invece di tutto ciò che corrisponde. Il \ u #### - \ u #### indica quali caratteri corrispondono. \ U0000- \ u007F è l'equivalente dei primi 255 caratteri in utf-8 o unicode, che sono sempre i caratteri ascii. Quindi abbinate ogni carattere non ascii (a causa del non) e fate una sostituzione su tutto ciò che corrisponde. 11 dic. 092009-12-11 21:11:26

+3

non 255, 127 .. sorry bout che Gamma :) 11 dic. 092009-12-11 21:12:13

+33

per i caratteri stampabili è 0020-007E, per persone in cerca di espressione regolare per sostituire non stampabili caratteri 17 feb. 142014-02-17 04:40:17

  0

Se si desidera visualizzare una tabella del set di caratteri ASCII: http: //www.asciitable.com/ 26 feb. 152015-02-26 15:06:05

  0

L'intervallo per ** ASCII esteso ** è \ u0000- \ u00FF, per gli utenti che cercano espressioni regolari per sostituire i caratteri ASCII non estesi (ad es. per app con lingua spagnola, segni diacritici, ecc ...) 29 dic. 152015-12-29 21:30:50

+1

@GordonTucker \ u0000- \ u007F è l'equivoco dei ** primi 127 caratteri ** in utf-8 o unicode e NON i primi 225. Vedere [tabella] (http://www.ascii-code.com/) 29 dic. 152015-12-29 21:33:56

+4

@full_prog_full che è il motivo per cui ho risposto a me stesso circa un minuto dopo mi correzione per dire che era 127 e non 255. :) 30 dic. 152015-12-30 21:46:35

  0

LED   Expo Thailandia è tutto pronto per la sua nuova edizione su   Tecnologia LED   come rimuovere il codice ASCII in C# 10 gen. 182018-01-10 11:46:58


96

Ecco una soluzione .NET puro che non utilizza le espressioni regolari:

 string inputString = "Räksmörgås"; 
     string asAscii = Encoding.ASCII.GetString(
      Encoding.Convert(
       Encoding.UTF8, 
       Encoding.GetEncoding(
        Encoding.ASCII.EncodingName, 
        new EncoderReplacementFallback(string.Empty), 
        new DecoderExceptionFallback() 
        ), 
       Encoding.UTF8.GetBytes(inputString) 
      ) 
     ); 

Può sembrare ingombrante, ma dovrebbe essere intuitivo. Utilizza la codifica .NET ASCII per convertire una stringa. UTF8 viene utilizzato durante la conversione perché può rappresentare uno qualsiasi dei caratteri originali. Utilizza un EncoderReplacementFallback per convertire qualsiasi carattere non ASCII in una stringa vuota.

+3

Perfetto! Lo sto usando per pulire una stringa prima di salvarla in un documento RTF. Davvero apprezzato. Molto più facile da capire rispetto alla versione Regex. 06 ott. 092009-10-06 16:48:26

+18

Hai davvero trovato più facile da capire? Per me, tutte le cose che non sono realmente rilevanti (fallback, conversioni in byte, ecc.) Distolgono l'attenzione da ciò che accade realmente. 11 ott. 092009-10-11 15:28:54

  0

devi amare quell'esempio! 16 mar. 112011-03-16 11:03:38

+18

È come dire che i cacciaviti sono troppo confusi, quindi userò solo un martello. 03 ago. 112011-08-03 22:05:12

+7

@Brandon, in realtà, questa tecnica non fa il lavoro meglio di altre tecniche. Quindi l'analogia dovrebbe usare un semplice cacciavite olde invece di un elegante iScrewDriver Deluxe 2000. :) 04 ago. 112011-08-04 07:46:09

  0

@bzim È come usare un martello su una vite :) OK no. Quindi è come usare l'albero motore del tuo motore per guidare una vite. Eccoci. 22 ago. 112011-08-22 17:10:45

  0

Quanto è lento rispetto alla regex? Regex è piuttosto veloce. 23 mag. 132013-05-23 21:09:24

  0

@InsidiousForce, probabilmente dipende da quale espressione regolare viene utilizzata. Perché non prendi una delle espressioni da una delle risposte a questa domanda e la confronti? :) 27 mag. 132013-05-27 08:36:34

+9

Un vantaggio è che posso facilmente sostituire ASCII con ISO 8859-1 o un'altra codifica :) 04 lug. 132013-07-04 03:34:35

  0

Abbiamo un DB di Foxpro che il nostro sistema utilizza, che viene danneggiato per un tempo passato. Poiché questa funzione viene eseguita su quasi tutti i campi di ogni riga, ero curioso di sapere la differenza di prestazioni e se c'era qualcosa di meglio della semplice espressione regolare. Per 1.000 stringhe unicode generate in modo casuale i tempi di esecuzione sono 'Regexp: Avg: 3 ~ 4ms, Max: 4ms' e' Conversione codifica: Avg: 4 ~ 5ms, Max: 7ms' (esclusa la generazione di stringhe, ovvero al di fuori del timer) 16 lug. 132013-07-16 11:46:05

  0

@ syserr0r Interessante. Questa tecnica potrebbe probabilmente essere ottimizzata, a seconda di cosa sta prendendo tempo. Le 2 istanze di fallback potrebbero essere riutilizzate, per esempio. 05 ago. 132013-08-05 12:20:18

  0

mi sto trovando questo per essere più veloce rispetto l'espressione regolare sulle corde più piccoli (sono quasi anche su 1000 stringa di caratteri) e più lenta su corde più grandi 02 ott. 142014-10-02 15:17:48

  0

chiedevo se potevo usare questo in qualche modo per sostituire i caratteri non ASCII con carattere di rimpiazzo. per esempio: 'á' sarebbe stato sostituito con' a'. È possibile? 28 dic. 152015-12-28 12:42:01

  0

@RageCompex EncoderReplacementFallback non è stato progettato per la conversione. Ma quello che vuoi può essere ottenuto utilizzando le API .NET per la normalizzazione Unicode e Canonicalizzazione. 30 dic. 152015-12-30 11:19:33


8

Ispirato da philcruz's Regular Expression solution, ho fatto una soluzione pura LINQ

public static string PureAscii(this string source, char nil = ' ') 
    { 
     var min = '\u0000'; 
     var max = '\u007F'; 
     return source.Select(c => c < min ? nil : c > max ? nil : c).ToText(); 
    } 

    public static string ToText(this IEnumerable<char> source) 
    { 
     var buffer = new StringBuilder(); 
     foreach (var c in source) 
      buffer.Append(c); 
     return buffer.ToString(); 
    } 

Si tratta di codice non testato.

+1

Per coloro che non l'hanno rilevato, questa è una soluzione basata su LINQ C# 4.0. :) 28 gen. 102010-01-28 20:49:59

+6

Invece del metodo separato ToText(), che ne dite di sostituire la linea 3 della PureAscii() con: restituire nuova stringa (source.Select (c => c <min nil:? C> Max Zero:? C) .ToArray()); 10 nov. 112011-11-10 05:51:56

  0

O forse ToText come: return (new string (source)). ToArray() - a seconda di cosa si ottiene meglio. È ancora bello avere ToText come metodo di estensione - fluente/stile pipeline. :-) 15 gen. 162016-01-15 10:14:21

  0

Questo codice sostituisce i caratteri non ASCII con uno spazio. Mettere a nudo fuori, cambiare Selezionare a Dove: 'restituire nuova stringa (source.Where (c => c> = min && c <= max) .ToArray());' 17 mag. 172017-05-17 20:53:52

  0

@Foozinator Che il codice consente di specificare quale personaggio per sostituire i caratteri non ASCII con. Di default usa uno spazio, ma se è chiamato come .PureASCII (Char.MinValue), sostituirà tutti i non-ASCII con '\ 0' - che ancora non li spoglia esattamente, ma risultati simili. 29 nov. 172017-11-29 16:42:41


13

Se si desidera non mettere a nudo, ma in realtà convertire latin accentati caratteri non accentati, dare un'occhiata a questa domanda: How do I translate 8bit characters into 7bit characters? (i.e. Ü to U)

  0

Non mi ero nemmeno reso conto che fosse possibile, ma per me è una soluzione molto migliore. Aggiungerò questo link a un commento sulla domanda per renderlo più semplice agli altri. Grazie! 10 dic. 132013-12-10 15:36:16


1

Ho usato questa espressione regex:

string s = "søme string"; 
    Regex regex = new Regex(@"[^a-zA-Z0-9\s]", (RegexOptions)0); 
    return regex.Replace(s, ""); 
+15

Rimuove anche la punteggiatura, nel caso non fosse quello che qualcuno vuole. 18 lug. 122012-07-18 08:43:26


4

ho trovato il seguente intervallo leggermente modificato è utile per analizzare i blocchi di commenti da un database, questo significa che non dovrete fare i conti con i caratteri tab e escape che causerebbero l'alterazione di un campo CSV.

parsememo = Regex.Replace(parsememo, @"[^\u001F-\u007F]", string.Empty); 

Se si vuole evitare altri caratteri speciali o punteggiatura particolare verificare the ascii table

+1

Nel caso in cui qualcuno non abbia notato gli altri commenti, i caratteri stampabili sono in realtà @ "[^ \ u0020- \ u007E]". Ecco un link per vedere il tavolo se sei curioso: http://www.asciitable.com/ 26 feb. 152015-02-26 15:03:47


6

senza bisogno di espressioni regolari. basta utilizzare la codifica ...

sOutput = System.Text.Encoding.ASCII.GetString(System.Text.Encoding.ASCII.GetBytes(sInput)); 
  0

+1 ottima risposta e la più semplice tra quelle elencate sopra ... 25 ago. 132013-08-25 09:50:07

+5

Questo non funziona. Questo non elimina i caratteri unicode, li sostituisce con il? carattere. 27 feb. 142014-02-27 16:56:11

+1

@David ha ragione. Almeno ho ottenuto '???? nacho ??' quando ho provato: 'た ま ね こ nacho な ち' in mono 3.4 06 ago. 142014-08-06 02:38:08

  0

È possibile creare un'istanza la propria classe di codifica che, invece di sostituire caratteri li rimuove. Vedere il metodo GetEncoding: https://msdn.microsoft.com/en-us/library/89856k4b(v=vs.110).aspx 01 apr. 162016-04-01 13:52:47


25

Credo MonsCamus significava:

parsememo = Regex.Replace(parsememo, @"[^\u0020-\u007E]", string.Empty); 
+1

IMHO Questa risposta è migliore rispetto alla risposta accettata perché estrae caratteri di controllo. 25 set. 172017-09-25 14:30:53

  0

LED &#160; Expo Thailandia è tutto pronto per la sua nuova edizione su &#160; LED &#160; tecnologia come rimuovere il codice ASCII in C# 10 gen. 182018-01-10 11:46:39


2

Questo non è ottimale prestazioni-saggio, ma una bella straight-forward approccio Linq:

string strippedString = new string(
    yourString.Where(c => c <= sbyte.MaxValue).ToArray() 
    ); 

Il Il rovescio della medaglia è che tutti i personaggi "sopravvissuti" vengono prima messi in una serie di tipo char[] che viene poi gettata via dopo che il costruttore string non la utilizza più.


2

Sono venuto qui cercando una soluzione per caratteri ascii estesi, ma non riuscivo a trovarlo. Il più vicino che ho trovato è bzlm's solution. Ma questo funziona solo con il codice ASCII fino a 127 (ovviamente è possibile sostituire il tipo di codifica nel suo codice, ma penso che sia stato un po 'complesso da capire. Quindi, condividendo questa versione). Ecco una soluzione che funziona per extended ASCII codes i.e. upto 255, che è la ISO 8859-1

Essa trova e ne estrae caratteri non ASCII (maggiore di 255)

Dim str1 as String= "â, ??î or ôu� n☁i✑++$-♓!‼⁉4⃣od;/⏬'®;☕:☝)///[email protected]#" 

Dim extendedAscii As Encoding = Encoding.GetEncoding("ISO-8859-1", 
               New EncoderReplacementFallback(String.empty), 
               New DecoderReplacementFallback()) 

Dim extendedAsciiBytes() As Byte = extendedAscii.GetBytes(str1) 

Dim str2 As String = extendedAscii.GetString(extendedAsciiBytes) 

console.WriteLine(str2) 
'Output : â, ??î or ôu ni++$-!‼⁉4od;/';:)///[email protected]#$%^yz: 

Ecco un working fiddle for the code

Sostituire la codifica secondo il requisito , il riposo dovrebbe rimanere lo stesso.


0

Uso questa espressione regolare per filtrare i caratteri non validi in un nome file.

Regex.Replace(directory, "[^a-zA-Z0-9\\:_\- ]", "") 

Dovrebbero essere tutti i caratteri consentiti per i nomi di file.

  0

Nope. Vedere [Path.GetInvalidPathChars] (https://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars (v = vs.110) aspx) e [Path.GetInvalidFileNameChars] (https://msdn.microsoft.com/en-us/library/system.io.path.getinvalidfilenamechars(v=vs.110).aspx). Quindi, ci sono decine di migliaia di caratteri validi. 10 giu. 172017-06-10 00:04:42

  0

Hai ragione, Tom. In realtà stavo pensando a quelli comuni, ma ho omesso parentesi e parentesi graffe e tutti questi - ^% $ # @! & + =. 12 giu. 172017-06-12 20:02:35