2009-10-05 23 views
37

Tengo una rutina C# que importa datos de un archivo CSV, los compara con una base de datos y luego los reescribe en un archivo. El archivo de origen parece tener algunos caracteres que no son ASCII y están ensuciando la rutina de procesamiento.Eliminar todos los caracteres no ASCII de la cadena

Ya tengo un método estático al que ejecuto cada campo de entrada pero realiza comprobaciones básicas como eliminar comas y comillas. ¿Alguien sabe cómo podría agregar funcionalidad que elimine también caracteres que no sean ASCII?

Respuesta

35
string sOut = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(s)) 
+9

Es importante tener en cuenta que el uso de asciiencoding reemplazará todos los caracteres no ASCII por '?' (63), que pueden ser o no lo que usted desea o espera . – captncraig

+11

Además, puede verificar si contiene solo ASCII, si 's == sOut' – Jaider

1

Suena extraño que se acepte dejar caer el no ASCII.

También siempre recomiendo la excelente biblioteca FileHelpers para analizar archivos CSV.

+0

+1 ¡Para el enlace FileHelpers! Parece muy útil. – amelvin

7

Si quería probar un carácter específico, se puede usar

if ((int)myChar <= 127) 

El simple hecho de la codificación ASCII de la cadena no le dirá que un carácter específico era no ASCII, para empezar (si se preocupan sobre eso). Ver MSDN.

48

Aquí una solución sencilla:

public static bool IsASCII(this string value) 
{ 
    // ASCII encoding replaces non-ascii with question marks, so we use UTF8 to see if multi-byte sequences are there 
    return Encoding.UTF8.GetByteCount(value) == value.Length; 
} 

fuente: http://snipplr.com/view/35806/

+2

Esta solución tiene la ventaja de funcionar en bibliotecas de clases portátiles, donde Encoding.ASCII no está disponible. –

+2

También tiene el beneficio de ser mucho más rápido que la solución aceptada porque no necesita crear una cadena codificada. –

+1

-1; la pregunta "funcionalidad que elimina caracteres que no son ASCII", lo que no funciona. El * título * fue ambiguo, pero la solución es aclarar el título (lo que hice), no responder a una pregunta que el OP no hizo. Esta podría ser una buena respuesta a una pregunta diferente a la que usted ha publicado, pero no responde a la que usted hizo. –

0
public string RunCharacterCheckASCII(string s) 
    { 
     string str = s; 
     bool is_find = false; 
     char ch; 
     int ich = 0; 
     try 
     { 
      char[] schar = str.ToCharArray(); 
      for (int i = 0; i < schar.Length; i++) 
      { 
       ch = schar[i]; 
       ich = (int)ch; 
       if (ich > 127) // not ascii or extended ascii 
       { 
        is_find = true; 
        schar[i] = '?'; 
       } 
      } 
      if (is_find) 
       str = new string(schar); 
     } 
     catch (Exception ex) 
     { 
     } 
     return str; 
    } 
8

hacerlo todo a la vez

public string ReturnCleanASCII(string s) 
{ 
    StringBuilder sb = new StringBuilder(s.Length); 
    foreach(char c in s) 
    { 
     if((int)c > 127) // you probably don't want 127 either 
      continue; 
     if((int)c < 32) // I bet you don't want control characters 
      continue; 
     if(c == ',') 
      continue; 
     if(c == '"') 
      continue; 
     sb.Append(c); 
    } 
    return sb.ToString(); 
} 
2

Aquí hay una mejora en la respuesta aceptada:

string fallbackStr = ""; 

Encoding enc = Encoding.GetEncoding(Encoding.ASCII.CodePage, 
    new EncoderReplacementFallback(fallbackStr), 
    new DecoderReplacementFallback(fallbackStr)); 

string cleanStr = enc.GetString(enc.GetBytes(inputStr)); 

Este método reemplazará caracteres desconocidos con el valor de fallbackStr, o si fallbackStr está vacío, déjelos fuera por completo. (Tenga en cuenta que enc se puede definir fuera del alcance de una función.)

Cuestiones relacionadas