删除 4 字节 UTF8 字符

本文关键字:字符 UTF8 字节 删除 | 更新日期: 2023-09-27 17:59:45

我想从字符串中删除以 ''xF0(带有 ASCII 代码 0xF0 的字符(开头的 4 字节 UTF8 字符并尝试

sText = Regex.Replace (sText, "'xF0...", "");

这行不通。使用两个反斜杠也不起作用。

确切的输入是 https://de.wikipedia.org/w/index.php?title=Spezial:Exportieren&action=submit&pages=Unicode 4 字节字符的内容是文本"[[Violinschlüssel]]"后面的字符,十六进制表示法:..0x65 0x6c 0x5d 0x5d 0x20 0xf0 0x9d 0x84 0x9e 0x20..预期输出为 0x65 0x6c 0x5d 0x5d 0x20 0x20 ..

怎么了?

删除 4 字节 UTF8 字符

此类字符将是使用 UTF-16 的 .NET 中的代理项对。它们中的每一个都是两个 UTF-16 代码单元,即两个char值。

要删除它们,您可以执行(using System.Linq;(:

sText = string.Concat(sText.Where(x => !char.IsSurrogate(x)));

(使用.NET 4.0(Visual Studio 2010(中引入的重载Concat(。


后期添加:使用可能会提供更好的性能:

sText = new string(sText.Where(x => !char.IsSurrogate(x)).ToArray());

即使看起来更糟。(适用于.NET 3.5(Visual Studio 2008(。

您正在尝试搜索byte值,但 C# 字符串是由char值组成的。"2.4.4.4 字符文本"部分中的 C# 语言规范指出:

字符

文本表示单个字符,通常由引号中的字符组成,如"a"。
...
十六进制转义序列表示单个 Unicode 字符,其值由 'x 后面的十六进制数字构成。

因此,搜索"'xF0..."是搜索字符U+F0,该字符将由字节C3 B0表示。

如果您想找到替换第一个字节为 0xF0 的所有 Unicode 字符,那么我相信您需要搜索第一个字节为 0xFO 的字符值。

字符U+10000表示为 F0 90 80 80(前面的代码是U+FFFF,即EF BF BF (。第一个带有 F1 .... .. 的代码是 U+40000 哪个是F1 80 80 80,它之前的值是U+3FFFF哪个是F0 BF BF BF

因此,您需要删除范围内的字符 U+10000U+3FFFF .这应该可以通过正则表达式来实现,例如

sText = Regex.Replace (sText, "[''x10000-''x3FFFF]", "");

问题中引用的来源中的相关字符已提取到下面的代码中。然后,代码尝试了解字符在字符串中的保存方式。

static void Main(string[] args)
{
    string input = "]    (";
    Console.Write("Input length  {0} : '{1}'  : ", input.Length, input);
    foreach (char cc in input)
    {
        Console.Write("  {0,2:X02}", (int)cc);
    }
    Console.WriteLine();
}

程序的输出如下。这支持了@Jeppe在他的回答中给出的代理对解释。

Input length  6 : '] ?? ('  :   5D  20  D834  DD1E  20  28