First, I printed out the unicode scalars in your string:
print(a.unicodeScalars.map { $0.value })
// [97, 10, 65039, 98]
And found out that your string indeed contains the line feed character \n
, which is the value 10
. However, it is followed by U+FE0F (65039), one of those variation selectors in unicode.
The overload of contains
you are calling here is contains(StringProtocol)
, not contains(Character)
. The former will perform a "smarter" kind of comparison, or as the Xcode's Quick Help documentation calls it, "non-literal":
Summary
Returns true iff other is non-empty and contained within self
by case-sensitive, non-literal search.
Discussion
Equivalent to self.rangeOfString(other) != nil
I can't seem to find this documentation online though... All I could find was this discussion showing contains
is smart enough to recognise that "ß" means "ss".
Anyway, the point is, contains
does not do a character-by-character search. It does whatever it think "makes sense".
Here are a few ways to make it print true
:
If you add the variation selector in to the argument to contains
, it prints true
:
print(a.contains("\n️")) // you can't see it, but there *is* a variation selector after the n
Check whether the unicodeScalars
contain the \n
character:
print(a.unicodeScalars.contains("\n"))
Use the contains(Character)
overload:
print(a.contains("\n" as Character))
Use range(of:)
with .literal
option:
print(a.rangeOfString("\n", options: [.literal]) != nil)