kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 TrueWill
TrueWill
Вопрос

Вычеркнуть метку порядка байтов из строки в C#

Я читал похожие сообщения об этом, но они не отвечают на мой вопрос.

В C# у меня есть строка, которую я получаю из WebClient.DownloadString. Я пробовал установить client.Encoding на new UTF8Encoding(false), но это ничего не изменило - я по-прежнему получаю метку порядка байт для UTF-8 в начале строки результата. Мне нужно удалить это (чтобы разобрать полученный XML с помощью LINQ), и я хочу сделать это в памяти.

Итак, у меня есть строка, которая начинается с \x00EF\x00BB\x00BF, и я хочу удалить ее, если она существует. Сейчас я использую

if (xml.StartsWith(ByteOrderMarkUtf8))
{
    xml = xml.Remove(0, ByteOrderMarkUtf8.Length);
}

но это кажется неправильным. Я пробовал всевозможные варианты кода с потоками, GetBytes и кодировками, но ничего не работает. Может ли кто-нибудь предоставить "правильный" алгоритм для удаления BOM из строки?

Спасибо!

42 2009-08-23T03:39:36+00:00 13
Программирование
encoding
c#
string
 PJUK
PJUK
4-го февраля 2011 в 4:59
2011-02-04T16:59:52+00:00
Дополнительно
Источник
Редактировать
#9399703

Недавно у меня были проблемы со .чистая 4 обновления, но до сих пор однозначного ответа

Строку.Отделка()`

удаляет Бом До .net 3.5 с Однако в .сеть 4, вам нужно немного изменить его

String.Trim(new char[]{'\uFEFF'});

Это также позволит избавиться от метки порядка байтов, хотя вы можете также хотеть удалить нулевой ширины пространства от U+200В

String.Trim(new char[]{'\uFEFF','\u200B'});

Это можно также использовать для удаления других нежелательных персонажей

Немного дополнительной информации от http://msdn.microsoft.com/en-us/library/t97s7bs3.aspx

Интернет .Framework 3.5 с пакетом обновления SP1 и более ранних версиях поддерживать внутренний список пробельные символы, что этот метод отделки. Начиная с .Чистая рамки 4, Этот метод удаляет все пробельные символы Юникода (то есть символы, которые производят True возвращаемое значение, если они передаются char.IsWhiteSpace метод). Из-за этого изменения, метод TRIM в .Framework 3.5 с пакетом обновления SP1 и более ранних версиях удаляет два символа, нулевой ширины пространства (U+200B) и нулевой ширины неразрывный пробел (U+FЭФФ), что метод уравновешивания в .Framework 4 и более поздние версии не удаляет. Кроме того, метод уравновешивания в .Framework 3.5 с пакетом обновления SP1 и более ранних версиях не обрезать три пробельные символы Unicode: монгольский гласные разделителя (U+180E), узкий неразрывный пробел (U+202F), и средний математические пробел (U+205F).

 PJUK
PJUK
Редактировал ответ 15-го мая 2014 в 9:22
46
0
 TrueWill
TrueWill
23-го августа 2009 в 6:38
2009-08-23T18:38:04+00:00
Дополнительно
Источник
Редактировать
#9399700

У меня были некорректные тестовые данные, что привело меня в замешательство. Основываясь на Как избежать спотыкания о UTF-8 BOM при чтении файлов, я обнаружил, что это работает:

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;
}

Установка свойства клиента Encoding правильно уменьшает BOM до одного символа. Однако XDocument.Parse по-прежнему не читает эту строку. Это самая чистая версия, которую я придумал на сегодняшний день.

 Community
Community
Редактировал ответ 23-го мая 2017 в 12:18
44
0
Vivek Ayer
Vivek Ayer
19-го июля 2010 в 4:22
2010-07-19T16:22:54+00:00
Дополнительно
Источник
Редактировать
#9399701

Это работает, как хорошо

int index = xmlResponse.IndexOf('<');
if (index > 0)
{
    xmlResponse = xmlResponse.Substring(index, xmlResponse.Length - index);
}
31
0
Решение / Ответ
Martin  v. L&#246;wis
Martin v. Löwis
23-го августа 2009 в 4:48
2009-08-23T04:48:34+00:00
Дополнительно
Источник
Редактировать
#9399698

Если переменная xml имеет тип string, то вы уже сделали что-то не так - в символьной строке BOM должен быть представлен не как три отдельных символа, а как одна кодовая точка. Вместо использования DownloadString, используйте DownloadData, а вместо нее разбирайте массивы байтов. Парсер XML должен сам распознать BOM и пропустить его (за исключением автоматического определения кодировки документа как UTF-8).

19
0
Tiago Gouv&#234;a
Tiago Gouvêa
25-го марта 2013 в 1:21
2013-03-25T13:21:49+00:00
Дополнительно
Источник
Редактировать
#9399705

Быстрый и простой способ, чтобы удалить его directyl из строки:

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", "");
}

Как использовать:

string yourCleanString=RemoveBom(yourBOMString);
13
0
Steven Oxley
Steven Oxley
27-го октября 2010 в 10:15
2010-10-27T22:15:15+00:00
Дополнительно
Источник
Редактировать
#9399702

У меня была очень похожая проблема (мне нужно для разбора XML-документа представляется в виде байтового массива, который имел метку порядка следования байтов в начале его). Я использовал один из Мартин'ы замечания по его ответу прийти к решению. Я взял массив байтов у меня (вместо преобразования его в строку) и созданный объект потоке MemoryStream с ним. Затем я передал XDocument используется.Нагрузки, который работал как шарм. Например, пусть&#39;ы сказать, чтоxmlBytes` содержит ваш XML в utf8 кодировке с байт-метка в начале его. Тогда это будет код, чтобы решить проблему:

var stream = new MemoryStream(xmlBytes);
var document = XDocument.Load(stream);

Это's, что простой.

Если начинаете со строкой, оно все равно должно быть легко сделать (допустим данных " XML " - это ваша строка, содержащая XML с метки порядка байтов):

var bytes = Encoding.UTF8.GetBytes(xml);
var stream = new MemoryStream(bytes);
var document = XDocument.Load(stream);
10
0
Andrew Thompson
Andrew Thompson
20-го февраля 2011 в 9:02
2011-02-20T21:02:24+00:00
Дополнительно
Источник
Редактировать
#9399704

Я написал следующее сообщение после прихода на этот вопрос.

По сути, вместо того, чтобы читать в необработанные байты файл'ы содержание с помощью класса BinaryReader, я использую streamreader класс с специальный конструктор, который автоматически удаляет метки порядка байтов персонаж из текстовых данных, я пытаюсь получить.

8
0
Andrew Arnott
Andrew Arnott
23-го августа 2009 в 4:49
2009-08-23T04:49:04+00:00
Дополнительно
Источник
Редактировать
#9399699

Передайте байтовый буфер (через DownloadData) в string Encoding.UTF8.GetString(byte[]), чтобы получить строку, а не загружать буфер КАК строку. Вероятно, у вас больше проблем с вашим текущим методом, чем просто обрезка знака порядка байтов. Если вы не декодируете его правильно, как я предлагаю здесь, символы Юникода, вероятно, будут неправильно интерпретированы, что приведет к повреждению строки.

Редактирование: Ответ Martin'а лучше, поскольку он позволяет избежать выделения целой строки для XML, который все равно нужно разбирать. Ответ, который я дал, лучше всего подходит для общих строк, которые не нужно разбирать как XML.

5
0
 Timothy
Timothy
20-го марта 2015 в 9:36
2015-03-20T21:36:04+00:00
Дополнительно
Источник
Редактировать
#9399707

Я столкнулся с этим, когда я был в base-64 шифрованный файл для преобразования в строку. В то время как я мог бы спасти его в файл и затем прочитать его правильно, здесь's лучшее решение я могу думать, чтобы получить от Байт[] файл в строку (опираясь слегка на 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);
    }
}

Где как startswith(байт[])` является логическим продолжением:

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;
}
3
0
Nicholas Petersen
Nicholas Petersen
26-го февраля 2019 в 10:07
2019-02-26T22:07:01+00:00
Дополнительно
Источник
Редактировать
#9399708

Это's, конечно, лучше, если вы можете снять ее, пока еще на уровне байтовый массив, чтобы избежать нежелательных подстрок / allocs. Но если у вас уже есть строка, это, пожалуй, самый простой и наиболее эффективный способ справиться с этим.

Использование:

            string feed = ""; // input
            bool hadBOM = FixBOMIfNeeded(ref feed);

            var xElem = XElement.Parse(feed); // now does not fail

    /// <summary>
    /// You can get this or test it originally with: Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())[0];
    /// But no need, this way we have a constant. As these three bytes `[239, 187, 191]` (a BOM) evaluate to a single C# char.
    /// </summary>
    public const char BOMChar = (char)65279;

    public static bool FixBOMIfNeeded(ref string str)
    {
        if (string.IsNullOrEmpty(str))
            return false;

        bool hasBom = str[0] == BOMChar;
        if (hasBom)
            str = str.Substring(1);

        return hasBom;
    }
Nicholas Petersen
Nicholas Petersen
Редактировал ответ 10-го апреля 2019 в 11:25
3
0
 lucasjam
lucasjam
28-го августа 2014 в 1:42
2014-08-28T13:42:03+00:00
Дополнительно
Источник
Редактировать
#9399706
StreamReader sr = new StreamReader(strFile, true);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(sr);
 siva.k
siva.k
Редактировал ответ 28-го августа 2014 в 1:48
2
0
 Vinicius
Vinicius
28-го августа 2019 в 7:07
2019-08-28T19:07:12+00:00
Дополнительно
Источник
Редактировать
#9399709

Еще один универсальный вариант, чтобы избавиться от UTF-8 Бом преамбуле:

var preamble = Encoding.UTF8.GetPreamble();
if (!functionBytes.Take(preamble.Length).SequenceEqual(preamble))
    preamble = Array.Empty<Byte>();
return Encoding.UTF8.GetString(functionBytes, preamble.Length, functionBytes.Length - preamble.Length);
0
0
Oleg Polezky
Oleg Polezky
9-го ноября 2019 в 9:46
2019-11-09T09:46:08+00:00
Дополнительно
Источник
Редактировать
#9399710

Я решил проблему с помощью следующего кода

using System.Xml.Linq;

void method()
{
    byte[] bytes = GetXmlBytes();
    XDocument doc;
    using (var stream = new MemoryStream(docBytes))
    {
        doc = XDocument.Load(stream);
    }
 }
0
0
Похожие сообщества 6
Microsoft Stack Jobs
Microsoft Stack Jobs
2 414 пользователей
Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks
Открыть telegram
С#
С#
2 330 пользователей
Стараемся не флудить. Пишем по делу. Правила: https://t.me/professorweb/430450 Для флуда @svoboda_obsh
Открыть telegram
CODE BLOG / C#
CODE BLOG / C#
1 763 пользователей
Чат для .NET разработчиков и C# программистов. По всем вопросам: @shwanoff Youtube-канал: https://youtube.com/codeblog Основной канал: @codeblog Вконтакте: https://vk.com/codeblog Правила: https://t.me/codeblog_csharp/246972 Вакансии по тегу #work
Открыть telegram
var chat = new Chat();
var chat = new Chat();
1 428 пользователей
Обсуждение вопросов по .NET Правила чата – https://blog.devdigest.today/chat-rules Чат для флуда – https://t.me/+zwxI91RGG6s2YzAy
Открыть telegram
C#/.NET Для Новичков
C#/.NET Для Новичков
293 пользователей
Группа создана для тех, кто изучает язык программирования C#. Верховный главнокомандующий: @BlackDeveloper Оффтоп - разрешен в меру, реклама - бан.
Открыть telegram
ext
ext
31 пользователей
Общение на темы YouTube канала и программирования. Вакансии не размещаем. Основной канал: @extremecode
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 1 день назад
2
Денис Васьков
Зарегистрирован 2 дня назад
3
Dima Patrushev
Зарегистрирован 4 дня назад
4
sirojidddin otaboyev
Зарегистрирован 1 неделю назад
5
Елена Гайдамамакинат
Зарегистрирован 1 неделю назад
ID
JA
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией