Tru*_*ill 42 c# string encoding
我已经阅读了类似的帖子,他们没有回答我的问题.
在C#中,我有一个我从WebClient.DownloadString获取的字符串.我已经尝试将client.Encoding设置为新的UTF8Encoding(false),但这没有任何区别 - 我仍然在结果字符串的开头以UTF-8的字节顺序标记结束.我需要删除它(用LINQ解析生成的XML),并希望在内存中这样做.
所以我有一个以\ x00EF\x00BB\x00BF开头的字符串,如果它存在,我想删除它.现在我正在使用
if (xml.StartsWith(ByteOrderMarkUtf8))
{
xml = xml.Remove(0, ByteOrderMarkUtf8.Length);
}
Run Code Online (Sandbox Code Playgroud)
但这感觉不对.我已尝试过各种带有流,GetBytes和编码的代码,但没有任何作用.任何人都可以提供"正确"算法从字符串中剥离BOM吗?
谢谢!
PJU*_*JUK 46
我最近遇到了.net 4升级的问题,但在此之前,答案很简单
String.Trim()
删除BOM直到.net 3.5但是在.net 4中你需要稍微改一下
String.Trim(new char[]{'\uFEFF'});
Run Code Online (Sandbox Code Playgroud)
这也将摆脱字节顺序标记,虽然您可能还想删除ZERO WIDTH SPACE U + 200B
String.Trim(new char[]{'\uFEFF','\u200B'});
Run Code Online (Sandbox Code Playgroud)
这也可以用来删除其他不需要的字符
来自http://msdn.microsoft.com/en-us/library/t97s7bs3.aspx的更多信息
.NET Framework 3.5 SP1和更早版本维护此方法修剪的内部空白字符列表.从.NET Framework 4开始,该方法修剪所有Unicode空格字符(即,在传递给Char.IsWhiteSpace方法时生成真实返回值的字符).由于此更改,.NET Framework 3.5 SP1和更早版本中的Trim方法删除了两个字符,ZERO WIDTH SPACE(U + 200B)和ZERO WIDTH NO-BREAK SPACE(U + FEFF),即Trim方法. NET Framework 4及更高版本不会删除.此外,.NET Framework 3.5 SP1和更早版本中的Trim方法不会修剪三个Unicode空白字符:MONGOLIAN VOWEL SEPARATOR(U + 180E),NARROW NO-BREAK SPACE(U + 202F)和MEDIUM MATHEMATICAL SPACE (U + 205F).
Tru*_*ill 44
我有一些不正确的测试数据,这让我有些困惑.基于如何避免在读取文件时跳过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;
}
Run Code Online (Sandbox Code Playgroud)
正确设置客户端编码属性会将BOM减少为单个字符.但是,XDocument.Parse仍然不会读取该字符串.这是我迄今为止提出的最干净的版本.
Viv*_*yer 31
这也有效
int index = xmlResponse.IndexOf('<');
if (index > 0)
{
xmlResponse = xmlResponse.Substring(index, xmlResponse.Length - index);
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*wis 19
如果变量xml是string类型,那么你已经做错了 - 在字符串中,BOM不应该表示为三个单独的字符,而应该表示为单个代码点.而不是使用DownloadString,使用DownloadData,而是解析字节数组.XML解析器应识别BOM本身,并跳过它(除了自动检测文档编码为UTF-8).
Tia*_*vêa 13
从字符串中删除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", "");
}
Run Code Online (Sandbox Code Playgroud)
如何使用:
string yourCleanString=RemoveBom(yourBOMString);
Run Code Online (Sandbox Code Playgroud)
Ste*_*ley 10
我有一个非常类似的问题(我需要解析一个表示为字节数组的XML文档,在其开头有一个字节顺序标记).我用马丁的一个评论来回答他的答案.我接受了我拥有的字节数组(而不是将其转换为字符串)并MemoryStream
使用它创建了一个对象.然后我把它传递给了XDocument.Load
,它就像一个魅力.例如,假设它xmlBytes
包含UTF8编码的XML,并在其开头有一个字节标记.然后,这将是解决问题的代码:
var stream = new MemoryStream(xmlBytes);
var document = XDocument.Load(stream);
Run Code Online (Sandbox Code Playgroud)
就这么简单.
如果从字符串开始,它仍然应该很容易(假设xml
您的字符串包含带字节顺序标记的XML):
var bytes = Encoding.UTF8.GetBytes(xml);
var stream = new MemoryStream(bytes);
var document = XDocument.Load(stream);
Run Code Online (Sandbox Code Playgroud)
传递字节缓冲区(通过DownloadData)来string Encoding.UTF8.GetString(byte[])
获取字符串而不是将缓冲区AS下载为字符串.当前方法可能比修剪字节顺序标记有更多问题.除非你按照我的建议正确解码它,否则unicode字符可能会被误解,从而导致字符串损坏.
编辑:Martin的答案更好,因为它避免为仍然需要解析的XML分配整个字符串.我给出的答案最适用于不需要解析为XML的通用字符串.
当然,最好还是在字节数组级别时将其删除,以避免不需要的子字符串/分配。但是如果你已经有了一个字符串,这可能是处理这个问题的最简单、最高效的方法。
用法:
string feed = ""; // input
bool hadBOM = FixBOMIfNeeded(ref feed);
var xElem = XElement.Parse(feed); // now does not fail
Run Code Online (Sandbox Code Playgroud)
/// <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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
63547 次 |
最近记录: |