相同的中文文本未通过平等测试

Gig*_*igi 1 c# string unicode character-encoding

我正在使用以下两个中文字符串进行测试:

\n\n
\xe2\x80\x8e\xe2\x80\x8e\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83\n
Run Code Online (Sandbox Code Playgroud)\n\n

...和...

\n\n
\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83\n
Run Code Online (Sandbox Code Playgroud)\n\n

它们看起来完全相同,但其实不然。在立即窗口中执行了以下测试:

\n\n
"\xe2\x80\x8e\xe2\x80\x8e\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83" == "\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83"\nfalse\n"\xe2\x80\x8e\xe2\x80\x8e\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83".Length + " " + "\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83".Length\n"12 10"\n
Run Code Online (Sandbox Code Playgroud)\n\n

还:

\n\n
"\xe2\x80\x8e\xe2\x80\x8e\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83"[0]\n8206 \'\xe2\x80\x8e\'\n"\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83"[0]\n20013 \'\xe4\xb8\xad\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我认为这可能与代理对有关,但我不明白为什么会发生这种情况。我发现很奇怪,你可以使用不同的二进制表示法来表示完全相同的中文文本。谁能解释一下这种现象吗?

\n

Ste*_*eri 5

其中有控制字符,因此在比较它们时需要使用 InvariantCulture 参数。

\n\n

看这个例子:

\n\n
var str1 = "\xe2\x80\x8e\xe2\x80\x8e\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83";\nvar str2 = "\xe4\xb8\xad\xe5\x9c\x8b\xe5\x93\xb2\xe5\xad\xb8\xe6\x9b\xb8\xe9\x9b\xbb\xe5\xad\x90\xe5\x8c\x96\xe8\xa8\x88\xe5\x8a\x83";\n\nConsole.WriteLine("str1 == str2 -> {0}", str1 == str2);\nConsole.WriteLine("str1 == str2 -> {0}", str1.Equals(str2,StringComparison.InvariantCulture));\n
Run Code Online (Sandbox Code Playgroud)\n\n

将为您提供以下输出:

\n\n
str1 == str2 -> False\nstr1 == str2 -> True\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如另一个很好的答案中指出的那样,代码 8206 是从左到右的标记。更多信息可以在这里找到

\n\n

InvariantCulture 比较忽略此类控制代码。更多信息可以在这里找到。相反,序数比较(默认)在字节级别工作。

\n\n

如果您想“清理”字符串中的任何控制字符,则无需迭代每个字符,相反,ReGex 可以为您提供帮助,如下所示:

\n\n
var cleanString = Regex.Replace(dirtyString, @"\\p{C}+", string.Empty);\n
Run Code Online (Sandbox Code Playgroud)\n