【问题标题】:Comparing strings that contain formatting in C#在 C# 中比较包含格式的字符串
【发布时间】:2023-10-23 05:54:01
【问题描述】:

我正在研究一个给定一些设置的函数 - 例如行间距,输出(以字符串形式)被修改。为了测试这样的场景,我使用了字符串字面量,预期结果如下所示。

该方法使用字符串生成器 (AppendLine) 生成所述输出。我遇到的一个问题是比较这些字符串。在下面的示例中,两者在所代表的方面是相同的。结果是我关心的区域,但是当比较两个字符串时,一个是文字,一个不是,相等自然会失败。这是因为其中一个字符串发出行间距,而另一个只显示它包含的格式。

解决这个平等问题的最佳方法是什么?我确实关心方法结果中的格式,例如换行,这是至关重要的。

代码:

string expected = @"Test\n\n\nEnd Test.";
string result = "Test\n\n\nEnd Test";

Console.WriteLine(expected);
Console.WriteLine(result);

输出:

测试\n\n\n结束测试。 测试 结束测试

【问题讨论】:

  • 为什么你测试@"Test\n\n\nEnd Test."而不是实际预期输出"Test\n\n\nEnd Test"?没有@就设置预期......
  • @tananscius 原来这是我开始做的,而且实际上是正确的。我已经添加了一个答案作为对此的跟进。

标签: c# string equality


【解决方案1】:

@ 前缀告诉编译器完全按照写入的方式获取字符串。因此,它不会将 \n 字符格式化为回车符和换行符。

由于分配给 result 变量的字符串的前缀不同,因此编译器会对其进行格式化。如果您想继续使用 @ 前缀,只需执行以下操作:

    string expected = @"Test


End Test";

您必须在字符串中输入回车符和换行符作为不可见字符。

【讨论】:

  • 这被称为“逐字字符串文字”。如果您想查看有关它的一些 MSDN 文档,您可以将其用作搜索。
【解决方案2】:

您错误地使用了“文字”一词​​。 “文字”仅表示代码中存在的实际值。换句话说,值在代码中以变量(为简单起见,我在这组中包括常量)和文字的形式存在。变量是一个值的抽象概念,而文字是一个值

所有这一切都是说您的两个字符串都是字符串文字,因为它们被硬编码到您的应用程序中。 @ 前缀只是表明编译器将在字符串中包含转义字符(实际上,除了双引号之外的任何字符),而不是在将字符串文字编译到程序集中时评估转义序列。

首先,无论您的函数返回什么(包含换行符的标准转义序列而不是换行符本身的字符串,或者实际包含换行符的字符串)都是您的测试变量应该包含的内容。使您的测试尽可能接近实际输出,因为您将值按摩成可比较形式的工作越多,您必须测试的代码路径就越多。如果您希望能够将带有嵌入其中的格式化转义序列的字符串与已评估这些序列的字符串进行比较(本质上是比较示例中的两个字符串),那么我会这样说:

  1. 确保这是您真正想做的事情。
  2. 在解释这些值并将“格式字符串”转换为“格式化字符串”时,您必须复制 C# 编译器的功能。

对于 #2,RegEx 处理器可能是最简单的选择。有关 C# 字符串转义序列的列表,请参阅 this page

【讨论】:

  • 只是为了补充术语课,以@为前缀的字符串文字是逐字字符串文字
【解决方案3】:

我觉得有点开明,但对我的发现感到恼火。

这是我第一个使用 MSTest 的项目,在测试失败后,我选择了查看测试详细信息来查看我的测试失败的原因和原因。此详细信息显示中字符串输出的格式很差,例如您得到:

Assert.AreEqual failed. Expected:<TestTest End>. Actual:<TestTest End>.

这是针对格式化文本的 - 奇怪的是,如果您使用 /r(换行符)而不是换行符 (/n),那么格式实际上是正确的。

事实证明,您可以在 debug 模式下查看运行测试所需的正确输出。换句话说,当你有一个失败的测试时,在调试中运行测试,异常将被捕获并显示如下:

Assert.AreEqual failed. Expected:<Test


Test End>. Actual:<Test


 Test End>.

上面显然包含正确的格式。

最后事实证明,我最初在字符串中存储期望(带格式)的方法是正确的,但我对 MSTest 的不熟悉让我质疑我的方法,因为它似乎是有效的输入,但只是被显示回我自己出现在一个有效的输出中。

【讨论】:

    【解决方案4】:

    在进行比较之前使用正则表达式去除空格?

    【讨论】:

    • 不是空格而是换行符。没有正则表达式的示例:*.com/questions/238002/…
    • 我认为 Ian 的意思是去除空白、换行符、返回等。从技术上讲,换行符不是空白,因为它不提供水平空白空格,但在某种意义上它仍然是一个“不可见”字符。
    最近更新 更多