如何在不分配字符串的情况下将 UTF-8 转义字节数组转义为未转义字节数组



我有一个表示转义字符串 UTF-8 的Span<byte>,如下所示:

二进制表示:byte[20] { 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 32, 92, 117, 50, 48, 97, 99, 32, 33 }

逃脱代表:"Hello world u20ac !"

所需的二进制结果:byte[17] { 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 32, 226, 130, 172, 32, 33 }

我尝试使用GetString()方法对转义的u20ac进行转码:Encoding.UTF8.GetBytes(Encoding.UTF8.GetString())

但这并不能逃避输入。

有什么方法可以达到相同的结果吗?

// Not working solution
public void NotWorkingUnescape(ReadOnlySpan<byte> source, Span<byte> destination)
{
var tmp = Encoding.UTF8.GetString(source);
Encoding.UTF8.GetBytes(tmp, destination);
}
// Unknown solution
// UTF-8 escaped byte array -> UTF8-8 unescaped byte array
public void FastUnescape(ReadOnlySpan<byte> source, Span<byte> destination)
{
// ?
}

您是否正在寻找一种可以完成所有工作的方法?

你可以简单地使用它:

public void FastUnescape(ReadOnlySpan<byte> source, Span<byte> destination)
{
Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(source), destination);
}

或防止任何异常:

public void FastUnescape(ReadOnlySpan<byte> source, Span<byte> destination)
{
if (source.Length <= destination.Length)
{
Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(source), destination);
}
}

更新:

还有另一种方法可以在不使用Encoding.UTF8的情况下进行转换,通过查看@JonSkeet响应,您可以实现以下内容:

public static void AnotherMethod(ReadOnlySpan<byte> source, Span<byte> destination)
{
for (int i = 0; i < source.Length; i++)
{
destination[i] = (byte) (Convert.ToChar(source[i]));
}
}

此代码的问题在于,当使用 Convert.toChar 时,转换为等效的 Unicode 字符而不是 UTF-8 字符,这就是为什么在答案的帖子中使用& 0x7f来获取 ASCII 范围内的值的原因。

我没有对您想要转义的其他特殊字符的性能或功能进行很多测试,但是我取得了相同的结果

相关内容

最新更新