C#의 문자열에서 바이트 순서 표시 제거하기

이와 유사한 게시물을 읽었지만 제 질문에 대한 답변이 없습니다.

C#에서 WebClient.DownloadString에서 가져오는 문자열이 있습니다. client.Encoding을 새로운 UTF8Encoding(false)으로 설정해 보았지만 아무런 차이가 없었으며 결과 문자열의 시작 부분에 UTF-8에 대한 바이트 순서 표시가 여전히 남아 있습니다. 이 부분을 제거해야 하는데(LINQ로 결과 XML을 구문 분석하기 위해) 메모리에서 제거하려고 합니다.

그래서 \x00EF\x00BB\x00BF로 시작하는 문자열이 있는데, 이 문자열이 존재한다면 제거하고 싶습니다. 현재 저는

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

를 사용하고 있지만 뭔가 잘못된 것 같습니다. 스트림, GetBytes 및 인코딩을 사용하여 모든 종류의 코드를 시도했지만 아무것도 작동하지 않습니다. 누구든지 문자열에서 BOM을 제거하는 올바른 알고리즘을 제공할 수 있나요?

감사합니다!

하지만 최근 4 업그레이드합니다 닷넷 (.net) 기반 단순 답이 그 때까지 내가 문제를 가지고 있었다

'스트라이스트림 ()'

bom 까지 절감뿐만 .net 3.5 그러나 4 .net 에서는 약간 변경하십시오 합니다.

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

또한 없앨 수 있는 의 바이트 순서 표식, 너비 傍埃 U + 200B 표시되어도 제거할 수도 있습니다.

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

이 다른 원치 않는 자를 제거하는 데 사용할 수도 있습니다

일부) 에서 자세한 내용은 http://msdn.microsoft.com/en-us/library/t97s7bs3.aspx

&gt. Net framework 3.5 sp1 이 방법을 지속적으로 공백 문자 및 이전 버전은 내부 목록니다 트리밍하며. Net framework 4 를 시작으로 모든 유니코드 문자를 메서드입니다 트림하여 공백 (즉, 그들이 진정한 가치를 만들어내는 문자이어야 복귀하십시오 하리아휘테스파스 메서드로부터 옮겨짐). Net framework 3.5 sp1 트리밍할 바꼈소, 이 때문에 이 방법을 절감뿐만 와 이전 버전 2 자, 너비 공간 (u + 200b) 과 너비 비분할 공간 (u+feff), 그 방법을 .net framework 4 이상에서는 트리밍할 없어지지 않습니다. Net framework 3.5 sp1 트리밍할 또 방법을 및 이전 버전은 세 가지 유니코드 트리밍할 언약보다는 공백 문자: 몽골 홀소리 seperator (U + 180E) 간에, 좁은 공간 (U + 202F) 및 중간 수학적 공간 (U + 205F).

해설 (6)

테스트 데이터가 잘못되어 혼동을 일으켰습니다. 파일을 읽을 때 UTF-8 BOM에 걸려 넘어지지 않는 방법]1을 참고하여 이 방법이 효과가 있다는 것을 알았습니다:

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

클라이언트 인코딩 속성을 올바르게 설정하면 BOM이 단일 문자로 줄어듭니다. 그러나 XDocument.Parse는 여전히 해당 문자열을 읽지 않습니다. 이것은 제가 지금까지 생각해낸 가장 깔끔한 버전입니다.

해설 (6)

이 기능은 물론


int index = xmlResponse.IndexOf('
해설 (4)
해결책

변수 xml이 문자열 유형인 경우 이미 뭔가 잘못한 것입니다. 문자열에서 BOM은 세 개의 개별 문자가 아니라 단일 코드 포인트로 표시되어야 합니다. DownloadString을 사용하는 대신 DownloadData를 사용하고 바이트 배열을 파싱하세요. XML 구문 분석기는 BOM 자체를 인식하고 이를 건너뛰어야 합니다(문서 인코딩을 UTF-8로 자동 감지하는 경우는 제외).

해설 (4)

빠르고 간단한 방법을 디르치일 분리하십시오 문자열에서:

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

How to use.

string yourCleanString=RemoveBom(yourBOMString);
해설 (5)

내가 가진 매우 유사한 문제 (내가 필요한 분석할 수 있는 XML 문서 표시된 바이트입니다 어레이입니다 바이트 순서 표식 처음부터 했다 (it). # 39 에 대한 설명 중 하나를 사용한 Martin& 내가 그의 답변은 오지 솔루션. 난 내가 가진 데 이어 바이트입니다 어레이입니다 아닌 문자열으로 변환하여) '와' 객체에는 미모리스트림 만들고 있습니다. 그 후 ',' 매력 있는 통과했어 redhat. 스도쿠망드로이드 같이 일했다. 예를 들어, that 's # 39 라고 let& 스마르비츠' 들어 XML utf8 인코딩입니다 수신기마다 바이트입니다 lesher 처음부터 것이다. 그런 다음 이 문제를 해결하기 위해 약간만이라도 코드:

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

39 에 있는 it& 단순해졌습니다.

시작 아웃해야 문자열으로 계속 쉽게 수행할 수 있는 경우 반드시 (solaris. 'xlm' 는 자신의 포함하는 문자열이 있는 XML 바이트 순서 표식):

var bytes = Encoding.UTF8.GetBytes(xml);
var stream = new MemoryStream(bytes);
var document = XDocument.Load(stream);
해설 (4)

정보정의다음 게시물로의 '라고 필리핀으로 구현하므로 내가 이 문제를 해결할 수 있습니다.

39 의 s 내용, 본질적으로 있는 대신 판독값 기초형상 바이트입니다 file& 비나리레이더 사용하여 클래스를 사용하여 클래스를 자동으로 조정하는 내가 스트림레이더 sys_memsize 특정 구성자를 에서 문자 텍스트 데이터를 검색하는 실로나는 바이트 순서 표식 제거합니다.

해설 (0)

다운로드 데이터를 통해 바이트 버퍼를 문자열로 다운로드하는 대신 문자열을 가져 오려면 string Encoding.UTF8.GetString(byte[])에 바이트 버퍼를 전달하십시오. 현재 방법에는 바이트 순서 표시를 다듬는 것보다 더 많은 문제가 있을 수 있습니다. 여기서 제안한 대로 제대로 디코딩하지 않으면 유니코드 문자가 잘못 해석되어 문자열이 손상될 수 있습니다.

편집: 어쨌든 구문 분석이 필요한 XML에 전체 문자열을 할당하는 것을 피할 수 있으므로 Martin의 답변이 더 좋습니다. 제가 제공한 답변은 XML로 구문 분석할 필요가 없는 일반 문자열에 가장 적합합니다.

해설 (2)

이 때 나는 내가 로 인코딩된 파일을 실행했음 인도하심이라만일 base-64 변형하려면 꽂으십시오 구체화하십시오. 내가 할 수 있는 동안 제대로 읽어 # 39 에 저장된 파일을 클릭한 다음 redhat. here& 생각할 수 있어요 '에서' 최상의 솔루션을 afaq 바이트입니다 [] 의 파일을 문자열 (기반 가볍게 TrueWill& # 39 에 대한 답):

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

여기서 '스테이츠비트 (바이트입니다 [])' 는 논리적 확장명은:

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;
}
해설 (1)

39 의 물론 스트립 아웃해야 it& 수 있다면 피할 수 있는 최고의 수준을 유지하면서 바이트입니다 어레이입니다 원치 않는 서브문자열을 / 할당이. 하지만 이미 있는 경우, 이는 아마도 가장 쉽고 강력한 이겨낼 수 있는 방법을 문자열으로.

사용법:

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

            var xElem = XElement.Parse(feed); // now does not fail
    /// 
    /// 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.
    /// 
    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;
    }
해설 (1)
StreamReader sr = new StreamReader(strFile, true);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(sr);
해설 (2)

또 다른 일반 변형된 UTF-8 BOM 값으로 프리앰블:

var preamble = Encoding.UTF8.GetPreamble();
if (!functionBytes.Take(preamble.Length).SequenceEqual(preamble))
    preamble = Array.Empty();
return Encoding.UTF8.GetString(functionBytes, preamble.Length, functionBytes.Length - preamble.Length);
해설 (0)

내가 이 문제를 해결한 다음 코드를 사용하여

using System.Xml.Linq;

void method()
{
    byte[] bytes = GetXmlBytes();
    XDocument doc;
    using (var stream = new MemoryStream(docBytes))
    {
        doc = XDocument.Load(stream);
    }
 }
해설 (0)