NUnit - 如何比较包含复合Unicode字符的字符串?
我使用NUnit v2.5来比较包含复合Unicode字符的字符串。
虽然比较本身工作正常,但表明第一个区别的插入符号似乎错位。NUnit - 如何比较包含复合Unicode字符的字符串?
UPD:我已经结束了与重写EqualConstraint
,反过来调用自定义TextMessageWriter
,所以我不再需要一个答案。请参阅以下解决方案。
这里的片段:
string s1 = "ใช้งานง่าย";
string s2 = "ใช้งานงาย";
Assert.That(s1, Is.EqualTo(s2));
这里的输出:
Expected: "ใช้งานงาย"
But was: "ใช้งานง่าย"
------------------^
指示第一不同的字符中的箭头似乎是关闭2个位置(多达有音以上标记)。对于更长的琴弦,它变成了一个真正的痛苦。我试过String.Normalize()
但它也不管用。
我该如何解决这个问题?感谢您的帮助。请参阅下面的答案。
您应该可以使用this answer中的代码将每个字符串转换为原始字符串的转义版本。复合字符将成为一个单一的密码转义,而组合字符将是一系列这样的转义。然后在这些字符串的转义版本上运行您的Assert
。
当您比较Unicode字符串时,必须始终对比较的两侧进行标准化,并且采用相同的方式。对s1
和s2
进行二进制比较是不够的,因为典型的等价字符串不会测试二进制等价。
对于四种标准化形式中的每一种,存在四个微不足道的归一化函数,您可能想要测试NFD(s1)
二进制等于NFD(s2)
。在那里使用NFD
或NFC
并不重要,但是您必须对两个字符串都做同样的事情。
对于k-compat函数,NFKD和NFKD,这些函数在进行字符串搜索时很有用,因为它们以某种精度为代价提高了查全率。例如NFKD("™")
将等于NFKD("TM")
。例如,当您在文档上运行搜索时,Adobe Reader会执行此操作:它始终以k-compat模式运行搜索,以便您的搜索更有机会找到所需内容。但是,与NFC
和NFD
不同,k-compat函数NFKC
和NFKD
会丢失信息并且不可逆。然而,使用简单的NFD
和NFC
,您总是可以回到另一个。
谢谢您的想法。比较本身按预期工作;我认为它始终是二进制的。 问题只与一个指示箭头有关。 NUnit似乎基于char偏移量计算其长度。 “ใช้”和“ใช”分别占用两个占位符,而字符串长度分别为3和2。 此外,请注意差异发生得更多,但这个词(样本中的第一个词)也会导致错误的偏移量。 – bytebuster 2012-02-28 23:15:19
@bytebuster其中一个字符串中有U + 0348'THAI CHARACTER MAI EK',另一个字符串缺少。这个角色既是'\ p {Diacritic}'也是'\ p {Nonspacing_Mark}'字符。有一个字符串,它不会再像没有它的字符串一样,那么咖啡厅*或*niño*会和* cafe *和* nino *一样。 Unicode确实有一种容忍这种差异的平等测试,但不是标准化。相反,它只是使用Unicode归类算法以主要强度进行比较。因此,您需要将UCA1(s1)与UCA1(s2)进行二进制比较。 – tchrist 2012-02-28 23:23:31
我明白你在Unicode方面的含义,但我不认为这对NUnit有什么帮助。用两个词来表达:我唯一需要的是箭头缩短了两个字符,例如' - ^'而不是'---- ^'。你能否详细说明你的建议? – bytebuster 2012-02-28 23:37:41
不幸的是,这不是一种选择。正确地指向十六进制转储中间的箭头将更难以解释,与指向原始文本的_misplaced_箭头相比... – bytebuster 2012-02-28 23:28:24