删除4个字节的UTF8字符

时间:2016-08-02 07:49:05

标签: c# regex utf-8

我想从字符串中删除以\ 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 ..

怎么了?

2 个答案:

答案 0 :(得分:5)

这些字符将是.NET中使用UTF-16的代理对。它们中的每一个都是两个 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)。)

答案 1 :(得分:2)

您正在尝试搜索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