C# 删除4字节UTF8字符

C# 删除4字节UTF8字符,c#,regex,utf-8,C#,Regex,Utf 8,我想从字符串中删除以\xF0(ASCII代码为0xF0的字符)开头的4字节UTF8字符,然后重试 sText = Regex.Replace (sText, "\xF0...", ""); 这不管用。使用两个反斜杠也不起作用 确切的输入是文本“[[Violinschlüssel]]”后面的4字节字符的内容,以十六进制表示:。。0x65 0x6c 0x5d 0x5d 0x20 0xf0 0x9d 0x84 0x9e 0x20。。预期输出为0x65 0x6c 0x5d 0x5d 0x20 0x20

我想从字符串中删除以\xF0(ASCII代码为0xF0的字符)开头的4字节UTF8字符,然后重试

sText = Regex.Replace (sText, "\xF0...", "");
这不管用。使用两个反斜杠也不起作用

确切的输入是文本“[[Violinschlüssel]]”后面的4字节字符的内容,以十六进制表示:。。0x65 0x6c 0x5d 0x5d 0x20 0xf0 0x9d 0x84 0x9e 0x20。。预期输出为0x65 0x6c 0x5d 0x5d 0x20 0x20


怎么了?

您正在尝试搜索
字节
值,但C#字符串是由
字符
值组成的。“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
)。带有
F1的第一个代码
U+40000
,它是
F1 80
,之前的值是
U+3FFFF
,它是
F0 BF

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

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

问题中引用的源代码中的相关字符已提取到下面的代码中。然后,代码尝试理解字符是如何保存在字符串中的

static void Main(string[] args)
{
    string input = "] Such characters will be surrogate pairs in .NET which uses UTF-16. Each of them will be two UTF-16 code units, that is two 
char
values.

To just remove them, you can do (
using System.Linq;
):

sText = string.Concat(sText.Where(x => !char.IsSurrogate(x)));
static void Main(字符串[]args)
{
string input=“]这些字符将是使用UTF-16的.NET中的代理项对。每个字符将是两个UTF-16代码单元,即两个
char

要删除它们,您可以(
使用System.Linq;
)执行以下操作:

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


后期添加:它可以提供更好的性能来使用:


即使它看起来更糟。(在.NET3.5(VisualStudio2008)中工作)

使用两个反斜杠。可能是因为您试图删除。您的确切输入和确切预期输出是什么?我们将要求您进行澄清。请单击链接并更新您的帖子,将您的澄清放在问题本身。这是一个好问题。它涉及字节、字符之间不明显的关系和C#中的字符串。我需要使用“UTF8”编码将数据存储在MySQL数据库中(目前无法更改)。请参阅@Qix为什么要修改语言标准中的直接引用?引用的部分没有任何粗体文本,并且使用字符串引号。请解释。因为它更好地强调了您的观点。它没有改变规范的含义。我必须搜索您包含单个cha符号的原因Racker和不得不搜索真正的答案,这是unicode
char
和单个
byte
@Qix之间的区别我的答案的第一句话提到了C中
char
byte
之间的区别。非常感谢。这很可能指向了正确的方向,但您的解决方案仍然不正确工作。它从输入中删除了很多字符,但没有删除4字节UTF8字符。即使是
Regex.Replace(sText,“\\x1D11E”,”)
也没有从输入中删除精确的单个字符。据我所知,它删除了所有3字节和4字节UTF8字符(这是C#字符串中的2个UTF16字符值)。这不完全是我要求的,但我发现这正是我真正需要的。再次感谢。@André你错了。如果你想删除对应于3字节UTF-8或更长的字符,只需使用
sText=string.Concat(sText.Where(x=>x<'\u0800'))
.UTF-8可以在文件中使用,但一旦
字符串
进入内存,.NET或Windows就不会使用它。如果一个字符在UTF-8中需要1、2或3个字节,它可以放在一个代码单元中(即一个
字符
值)在UTF-16中,它是.NET和Windows内部使用的编码。如果一个字符需要UTF-8中的4个字节,它需要两个UTF-16代码单元(因此有两个
char
值);这两个值构成“代理项对”。
sText = new string(sText.Where(x => !char.IsSurrogate(x)).ToArray());