NSString的isEqualToString方法返回异常结果

3

我经常遇到一些(罕见的)情况,即使在控制台中打印出来看起来完全一样的NSStrings,但它们并不相等。例如:

[string1 isEqualToString:string2]
> comparing 'angelo debarre' to 'angelo debarre'

一直返回NO。我尝试使用NSString的stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet],但仍然没有成功。我也尝试使用比较器如compare:localizedCaseInsensitiveCompare:,但是我一直得到相同的结果。有什么我可能忽略的东西吗?


一个看起来像空格但实际上不是的字符(或其他Unicode奇怪现象)。考虑将字符串转储为十六进制。如果那些值相同... - user166390
2个回答

7
尝试使用NSString的Unicode规范化函数之一来分解字符串,例如- (NSString *)decomposedStringWithCompatibilityMapping。兼容映射(而不是规范映射)应该是您想要的,因为它将视觉上相似的字符序列分解为相同的基本组件。我没有明确查找非间断空格是否规范化为空格,但应该可以。编辑:有两种类型的兼容映射规范化:分解和合成。组合版本是 - (NSString *)precomposedStringWithCompatibilityMapping 。不确定哪个在一般情况下更好,但 Unicode标准附录#15(Unicode规范化形式)对KC / KD形式有以下说明:

规范化形式KC还折叠了许多情况下不恰当区分的兼容等效字符之间的差异。例如,半角和全角片假名字符将规范化为相同的字符串,罗马数字及其字母等价物也是如此。

规范化形式KC和KD不能盲目地应用于任意文本。因为它们会删除许多格式设置的区别,所以它们将防止与许多旧字符集之间的往返转换,并且除非被格式设置所替换,否则它们可能会删除对文本语义重要的区别。最好将这些规范化形式视为大写或小写映射:在某些上下文中用于识别核心含义,但也执行可能并不总是适当的文本修改。它们可以更自由地应用于具有受限字符集的域。


这似乎只部分地解决了我的问题。它解决了我在原始问题中提出的“angelo debarre”示例,但其他情况仍然困扰着我。 - samvermette
1
尝试使用NFKC标准化形式 (- (NSString *)precomposedStringWithCompatibilityMapping)。你能提供另一个例子吗? - user244343
太好了,那个可行!请更新您的答案,我会接受它。谢谢! - samvermette
@darvids0n,decomposedStringWithCompatibilityMapping 是做什么用的?我不理解。 - Iulian Onofrei
@IulianOnofrei 请尽可能从开头阅读此文档:http://www.unicode.org/reports/tr15/tr15-23.html#Introduction 如果语言过于技术性,那么您可能不想使用此函数,因为您将无法理解它正在做什么,最好使用字符串compare:方法。您引用的特定函数相当于该文档中的_Normalization Form KD_。 precomposed...版本是_Normalization Form KC_。 - user244343

0

我敢打赌其中一个是空格,另一个是不间断空格。仅修剪前缀和后缀的字符,这不会影响内部空格。


谢谢你告诉我我的错误,但并没有提出实际的解决方案:P - samvermette
抱歉,先生。请看这里的空格规范化方法:https://github.com/Cocoanetics/NSAttributedString-Additions-for-HTML/blob/master/Classes/NSString+HTML.m - Cocoanetics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接