parse - string.format c# ejemplo
Strip Byte Order Marcar de cadena en C# (10)
Escribí la siguiente publicación después de encontrar este tema.
Esencialmente, en lugar de leer los bytes brutos del contenido del archivo utilizando la clase BinaryReader, utilizo la clase StreamReader con un constructor específico que elimina automáticamente el carácter de la marca de orden de bytes de los datos de texto que estoy tratando de recuperar.
He leído publicaciones similares sobre esto y no responden a mi pregunta.
En C #, tengo una cadena que estoy obteniendo de WebClient.DownloadString. Intenté configurar client.Encoding a la nueva UTF8Encoding (false), pero eso no importó; aún así termino con una marca de orden de bytes para UTF-8 al comienzo de la cadena de resultados. Necesito eliminar esto (para analizar el XML resultante con LINQ), y quiero hacerlo en la memoria.
Así que tengo una cadena que comienza con / x00EF / x00BB / x00BF, y quiero eliminar eso si existe. En este momento estoy usando
if (xml.StartsWith(ByteOrderMarkUtf8))
{
xml = xml.Remove(0, ByteOrderMarkUtf8.Length);
}
pero eso solo se siente mal. He intentado todo tipo de código con transmisiones, GetBytes y codificaciones, y nada funciona. ¿Alguien puede proporcionar el algoritmo "correcto" para quitar una lista de materiales de una cadena?
¡Gracias!
Esto funciona tan bien
int index = xmlResponse.IndexOf(''<'');
if (index > 0)
{
xmlResponse = xmlResponse.Substring(index, xmlResponse.Length - index);
}
Me encontré con esto cuando tenía un archivo codificado en base 64 para transformarlo en la cadena. Si bien podría haberlo guardado en un archivo y luego haberlo leído correctamente, aquí está la mejor solución que se me ocurrió para pasar del byte[]
del archivo a la cadena (Basándome ligeramente en la respuesta de TrueWill):
public static string GetUTF8String(byte[] data)
{
byte[] utf8Preamble = Encoding.UTF8.GetPreamble();
if (data.StartsWith(utf8Preamble))
{
return Encoding.UTF8.GetString(data, utf8Preamble.Length, data.Length - utf8Preamble.Length);
}
else
{
return Encoding.UTF8.GetString(data);
}
}
Donde StartsWith(byte[])
es la extensión lógica:
public static bool StartsWith(this byte[] thisArray, byte[] otherArray)
{
// Handle invalid/unexpected input
// (nulls, thisArray.Length < otherArray.Length, etc.)
for (int i = 0; i < otherArray.Length; ++i)
{
if (thisArray[i] != otherArray[i])
{
return false;
}
}
return true;
}
Pase el búfer de bytes (mediante DownloadData) a la string Encoding.UTF8.GetString(byte[])
para obtener la cadena en lugar de descargarla como una cadena. Probablemente tenga más problemas con su método actual que simplemente recortar la marca de orden de bytes. A menos que esté decodificando correctamente como sugiero aquí, los caracteres Unicode probablemente serán malinterpretados, dando como resultado una cadena dañada.
Editar : la respuesta de Martin es mejor, ya que evita asignar una cadena entera para XML que aún necesita ser analizada de todos modos. La respuesta que ofrecí se aplica mejor a cadenas generales que no necesitan ser analizadas como XML.
Recientemente tuve problemas con la actualización .net 4, pero hasta entonces la respuesta simple es
String.Trim()
elimina la lista de materiales hasta .net 3.5 Sin embargo, en .net 4 necesita cambiarlo ligeramente
String.Trim(new char[]{''/uFEFF''});
Eso también eliminará la marca de orden Byte, aunque también es posible que desee eliminar ZERO WIDTH SPACE U + 200B
String.Trim(new char[]{''/uFEFF'',''/u200B''});
Esto también se puede usar para eliminar otros caracteres no deseados
Alguna información adicional de http://msdn.microsoft.com/en-us/library/t97s7bs3.aspx
.NET Framework 3.5 SP1 y versiones anteriores mantienen una lista interna de caracteres de espacio en blanco que este método recorta. A partir de .NET Framework 4, el método recorta todos los caracteres de espacio en blanco de Unicode (es decir, caracteres que producen un verdadero valor de retorno cuando se pasan al método Char.IsWhiteSpace). Debido a este cambio, el método Trim en .NET Framework 3.5 SP1 y versiones anteriores elimina dos caracteres, ZERO WIDTH SPACE (U + 200B) y ZERO WIDTH NO-BREAK SPACE (U + FEFF), que el método Trim en. NET Framework 4 y versiones posteriores no se eliminan. Además, el método Trim en .NET Framework 3.5 SP1 y versiones anteriores no recorta tres caracteres Unicode de espacios en blanco: SEPARADOR DE LA VOTO MONGOLIANO (U + 180E), ESPACIO ESTRECHO SIN ROTURA (U + 202F) y ESPACIO MATEMÁTICO MEDIO (U + 205F).
Si la variable xml es de tipo cadena, ya hizo algo mal: en una cadena de caracteres, la lista de materiales no debe representarse como tres caracteres separados, sino como un único punto de código. En lugar de utilizar DownloadString, use DownloadData y analice las matrices de bytes en su lugar. El analizador XML debería reconocer la propia lista de materiales y omitirla (excepto para la detección automática de la codificación del documento como UTF-8).
Tenía un problema muy similar (necesitaba analizar un documento XML representado como una matriz de bytes que tenía una marca de orden de bytes al principio). Usé uno de los comentarios de Martin sobre su respuesta para llegar a una solución. Tomé la matriz de bytes que tenía (en lugar de convertirla en una cadena) y creé un objeto MemoryStream
con ella. Luego lo pasé a XDocument.Load
, que funcionó como un amuleto. Por ejemplo, supongamos que xmlBytes
contiene su XML en codificación UTF8 con una marca de byte al principio. Entonces, este sería el código para resolver el problema:
var stream = new MemoryStream(xmlBytes);
var document = XDocument.Load(stream);
Es así de simple.
Si comienza con una cadena, todavía debería ser fácil de hacer (supongamos que xml
es la cadena que contiene el XML con la marca de orden de bytes):
var bytes = Encoding.UTF8.GetBytes(xml);
var stream = new MemoryStream(bytes);
var document = XDocument.Load(stream);
Tuve algunos datos de prueba incorrectos, lo que me causó cierta confusión. Según cómo evitar tropezar con la lista de materiales de UTF-8 al leer los archivos , descubrí que esto funcionaba:
private readonly string _byteOrderMarkUtf8 =
Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
public string GetXmlResponse(Uri resource)
{
string xml;
using (var client = new WebClient())
{
client.Encoding = Encoding.UTF8;
xml = client.DownloadString(resource);
}
if (xml.StartsWith(_byteOrderMarkUtf8, StringComparison.Ordinal))
{
xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
}
return xml;
}
Configurar el cliente La propiedad de codificación reduce correctamente la lista de materiales a un solo carácter. Sin embargo, XDocument.Parse aún no leerá esa cadena. Esta es la versión más limpia que he encontrado hasta la fecha.
Un método rápido y simple para eliminarlo directamente de una cadena:
private static string RemoveBom(string p)
{
string BOMMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (p.StartsWith(BOMMarkUtf8))
p = p.Remove(0, BOMMarkUtf8.Length);
return p.Replace("/0", "");
}
Cómo utilizar:
string yourCleanString=RemoveBom(yourBOMString);
StreamReader sr = new StreamReader(strFile, true);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(sr);