Сначала я распечатал скаляры юникода в вашей строке:
print(a.unicodeScalars.map { $0.value })
// [97, 10, 65039, 98]
И обнаружил, что ваша строка действительно содержит символ перевода строки \n
, который является значением 10
. Однако за ним следует U + FE0F (65039), один из тех селекторов вариантов в юникоде.
Перегрузка contains
, которую вы вызываете, это contains(StringProtocol)
, а не contains(Character)
. Первый будет выполнять «более умное» сравнение, или, как это называется в документации по быстрой справке Xcode, «не буквальное»:
Сводка
Возвращает true, если other не является пустым и содержится в пределах self
с учетом регистра, не буквального поиска.
Обсуждение
Эквивалентно self.rangeOfString(other) != nil
Кажется, я не могу найти эту документацию в Интернете ... Все, что я смог найти, это это обсуждение , показывающее 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)