字符串中的`contains(“ \ n”)`字符串为false时返回false

时间:2020-05-28 09:35:35

标签: swift

let a = """
a
️b
"""
a.contains("\n") // false

返回之后,字符串中似乎有一个奇怪的字符。

a.forEach(){ c in
    print(Character(String(c)).asciiValue)
}

Output: 
Optional(97)
Optional(10) // the return 
nil
Optional(98)

这是contains方法的错误,导致在返回字符后面跟随一些奇怪的字符时会否定识别吗?

1 个答案:

答案 0 :(得分:1)

首先,我在您的字符串中打印出了unicode标量:

print(a.unicodeScalars.map { $0.value })
// [97, 10, 65039, 98]

并发现您的字符串确实包含换行符\n,即值10。但是,其后是U + FE0F(65039),它是Unicode中的variation selectors之一。

您在此处调用的contains的重载是contains(StringProtocol),而不是contains(Character)。前者将执行“更智能”的比较,或者如Xcode的快速帮助文档所说的那样,“非文字”:

摘要

如果other是非空的并且通过区分大小写的非文字搜索包含在self中,则返回true。

讨论

相当于self.rangeOfString(other) != nil

虽然我似乎无法在线找到该文档……我所能找到的只是this discussion,显示contains足够聪明,可以识别出“ß”代表“ ss”。

无论如何,重点是contains不会进行逐字符搜索。它会做它认为“有意义”的事情。

有几种方法可以打印true

  • 如果将变体选择器添加到contains的参数中,它将显示true

      print(a.contains("\n️")) // you can't see it, but there *is* a variation selector after the n
    
  • 检查unicodeScalars是否包含\n字符:

      print(a.unicodeScalars.contains("\n"))
    
  • 使用contains(Character)重载:

      print(a.contains("\n" as Character))
    
  • range(of:).literal选项一起使用:

      print(a.rangeOfString("\n", options: [.literal]) != nil)
    
相关问题