Как проверить, содержит ли строка другую строку в Swift?


535

В Objective-Cкоде для проверки подстроки в NSStringis:

NSString *string = @"hello Swift";
NSRange textRange =[string rangeOfString:@"Swift"];
if(textRange.location != NSNotFound)
{
    NSLog(@"exists");
}

Но как мне сделать это в Swift?


2
@rckoenes Я новичок в Swift, я знаю, как это сделать
Rajneesh071

1
Тогда почему бы вам не начать игровую площадку и не попробовать ее?
Rckoenes

Если вы все еще здесь, пожалуйста, измените принятый ответ на user1021430 ... это правильно
Дэн Розенстарк

Ответы:


1045

Вы можете сделать точно такой же вызов с Swift:

Свифт 4 и Свифт 5

В Swift 4 String представляет собой набор Characterзначений, в Swift 2 и 3 это было не так, поэтому вы можете использовать этот более краткий код 1 :

let string = "hello Swift"
if string.contains("Swift") {
    print("exists")
}

Swift 3.0+

var string = "hello Swift"

if string.range(of:"Swift") != nil { 
    print("exists")
}

// alternative: not case sensitive
if string.lowercased().range(of:"swift") != nil {
    print("exists")
}

Олд Свифт

var string = "hello Swift"

if string.rangeOfString("Swift") != nil{ 
    println("exists")
}

// alternative: not case sensitive
if string.lowercaseString.rangeOfString("swift") != nil {
    println("exists")
}

Я надеюсь, что это полезное решение, так как некоторые люди, включая меня, столкнулись с некоторыми странными проблемами при звонке containsString(). 1

PS. Не забудьimport Foundation

Сноски

  1. Просто помните, что использование функций сбора в строках имеет некоторые крайние случаи, которые могут дать вам неожиданные результаты, например, при работе с эмодзи или другими кластерами графем, такими как буквы с акцентом.

13
Документация Apple гласит: An NSRange structure giving the location and length in the receiver of the first occurrence of aString. Returns {NSNotFound, 0} if aString is not found or is empty (@"").Так что, может быть, просто проверка nilне будет работать должным образом.
Алекс

7
string.lowercaseString.rangeOfString ("swift"). location! = NSNotFound. Пожалуйста, прочитайте документацию .. Вы не получите нулевой объект обратно.
TheCodingArt

4
@TheGamingArt Да, вы будете. Свифт автоматически совершает все обходы, так что если NSRange это, {NSNotFound, 0}он представляется для вас как ноль. Если это фактический диапазон, он представляется вам как Swift Range (необязательно). Круто.
Мэтт

4
Grr. containsString не находится в документах, даже с Xcode 6.3.1.
Дункан С

19
@TheGoonie: Это не называет NSString«S .rangeOfString(). Это называет String's' .rangeOfString(), который объявлен какfunc rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
newacct

192

Способ расширения

Swift 4

extension String {
    func contains(find: String) -> Bool{
        return self.range(of: find) != nil
    }
    func containsIgnoringCase(find: String) -> Bool{
        return self.range(of: find, options: .caseInsensitive) != nil
    }
}

var value = "Hello world"

print(value.contains("Hello")) // true
print(value.contains("bo"))    // false

print(value.containsIgnoringCase(find: "hello"))    // true
print(value.containsIgnoringCase(find: "Hello"))    // true
print(value.containsIgnoringCase(find: "bo"))       // false

Как правило, Swift 4 содержит метод, однако он доступен из iOS 8.0+


Swift 3.1

Вы можете написать расширение contains:и containsIgnoringCaseдляString

extension String { 

   func contains(_ find: String) -> Bool{
     return self.range(of: find) != nil
   }

   func containsIgnoringCase(_ find: String) -> Bool{
     return self.range(of: find, options: .caseInsensitive) != nil 
   }
 }

Старая версия Swift

extension String {

    func contains(find: String) -> Bool{
       return self.rangeOfString(find) != nil
     }

    func containsIgnoringCase(find: String) -> Bool{
       return self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil
     }
}

Пример:

var value = "Hello world"

print(value.contains("Hello")) // true
print(value.contains("bo"))    // false

print(value.containsIgnoringCase("hello"))    // true
print(value.containsIgnoringCase("Hello"))    // true
print(value.containsIgnoringCase("bo"))       // false

6
чтобы игнорировать регистр, используйте return self.rangeOfString (find, options: NSStringCompareOptions.CaseInsensitiveSearch)! = nil
masgar

1
Больше не нужно, если у вас нет Foundationвокруг ... containsStringработает нормально.
Дэн Розенстарк

5
для быстрой 3.0. Перейдите к следующему: расширение String {func содержит (find: String) -> Bool {return self.range (of: find)! = Nil} func содержитIgnoringCase (find: String) -> Bool {return self.range (of: find , параметры: .caseInsensitive)! = nil}}
Майкл Шан

Для Swift 4 -> расширение String {func содержит (find: String) -> Bool {return self.range (of: find)! = Nil} func содержитIgnoringCase (find: String) -> Bool {return self.range (of: найти, параметры: .caseInsensitive)! = nil}}
shokaveli

50

Из документации кажется, что вызов containsString()строки должен работать:

Тип String Swift напрямую связан с классом Foundation NSString. Если вы работаете с платформой Foundation в Cocoa или Cocoa Touch, весь API NSString доступен для вызова любого значения String, которое вы создаете, в дополнение к функциям String, описанным в этой главе. Вы также можете использовать значение String с любым API, для которого требуется экземпляр NSString.

Однако, похоже, это не работает.

Если вы попытаетесь использовать someString.containsString(anotherString), вы получите ошибку времени компиляции, которая гласит'String' does not contain a member named 'containsString' .

Итак, у вас осталось несколько вариантов, один из которых - явно привязать ваш Stringк Objective-C с помощью bridgeToObjectiveC()двух других, включая явное использование, NSStringи последний - приведениеString кNSString

Соединяя мост, вы получите:

var string = "hello Swift"
if string.bridgeToObjectiveC().containsString("Swift") {
    println("YES")
}

Явно введя строку как NSString, вы получите:

var string: NSString = "hello Swift"
if string.containsString("Swift") {
    println("YES")
}

Если у вас есть существующий String, вы можете инициализировать NSString из него, используя NSString (string :):

var string = "hello Swift"
if NSString(string: string).containsString("Swift") {
    println("YES")
}

И, наконец, вы можете привести существующего Stringк NSStringкак показано ниже

var string = "hello Swift"
if (string as NSString).containsString("Swift") {
    println("YES")
}

4
Последний пример (я не пробовал другие) вылетает для меня на iOS 7 (устройство); Приложения Swift должны нормально работать на iOS 7. Я получаю ошибку [__NSCFString containsString:]: unrecognized selector sent to instance. Кроме того, я не могу найти метод containsStringв документации разработчика, чтобы подтвердить, является ли он новым для iOS 8.
Джейсон Лич

Интересно. Я проверял это только на детской площадке. Я попробую позже, когда буду на своем компьютере.
Цезарь

третий и четвертый варианты - единственные, которые разрешены компилятором. оба вылетели для меня в бета-версии 4 в iOS 7.
Palmi

38

Другой. Поддерживает регистр и диакритические опции.

Swift 3.0

struct MyString {
  static func contains(_ text: String, substring: String,
                       ignoreCase: Bool = true,
                       ignoreDiacritic: Bool = true) -> Bool {

    var options = NSString.CompareOptions()

    if ignoreCase { _ = options.insert(NSString.CompareOptions.caseInsensitive) }
    if ignoreDiacritic { _ = options.insert(NSString.CompareOptions.diacriticInsensitive) }

    return text.range(of: substring, options: options) != nil
  }
}

Применение

MyString.contains("Niels Bohr", substring: "Bohr") // true

iOS 9+

Функция, нечувствительная к регистру и диакритическим знакам, доступна с iOS 9.

if #available(iOS 9.0, *) {
  "Für Elise".localizedStandardContains("fur") // true
}

31

Начиная с Xcode 7.1 и Swift 2.1 containsString()у меня нормально работает.

let string = "hello swift"
if string.containsString("swift") {
    print("found swift")
}

Свифт 4:

let string = "hello swift"
if string.contains("swift") {
    print("found swift")
}

И пример Swift 4 без учета регистра:

let string = "Hello Swift"
if string.lowercased().contains("swift") {
    print("found swift")
}

Или используя Stringрасширение без учета регистра :

extension String {
    func containsIgnoreCase(_ string: String) -> Bool {
        return self.lowercased().contains(string.lowercased())
    }
}

let string = "Hello Swift"
let stringToFind = "SWIFT"
if string.containsIgnoreCase(stringToFind) {
    print("found: \(stringToFind)")  // found: SWIFT
}
print("string: \(string)")
print("stringToFind: \(stringToFind)")

// console output:
found: SWIFT
string: Hello Swift
stringToFind: SWIFT

3
вам нужно import Foundation, иначе это не сработает.
Андрей Черненко

Требуется любой import UIKitиз import Foundationних, по крайней мере, с iOS 11 и Swift 4.
Мюррей Сагал

Но это с учетом регистра. Как вы делаете сравнение при игнорировании дела. Как в Java String.equalsIgnoreCase (anotherString)?
zulkarnain шах

@zulkarnainshah Я добавил пример к ответу.
Мюррей Сагал

@MurraySagal Это все еще не регистронезный поиск. Вы конвертируете исходную строку в строчные, а затем явно сравниваете ее со строчными. Это сделает работу, но это не идеальный способ сделать это
zulkarnain shah

22

В Swift 4.2

использование

func contains(_ str: String) -> Bool

пример

let string = "hello Swift"
let containsSwift = string.contains("Swift")
print(containsSwift) // prints true

4
Обратите внимание, что для этого необходимо импортировать Foundation.
rmaddy

16

> В SWIFT 3.0

let str = "Hello Swift"
if str.lowercased().contains("Swift".lowercased()) {
    print("String Contains Another String")
} else {
    print("Not Exists")
}

Вывод

String Contains Another String

15

Вы можете сделать это очень легко в Swift, используя код:

let string = "hello Swift";
let subString = (string as NSString).containsString("Swift")
if(subString){println("Exist")}

10

Просто добавление к ответам здесь.

Вы также можете выполнить локальный тест без учета регистра, используя:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

Пример:

    import Foundation

    var string: NSString  =  "hello Swift"
   if string.localizedCaseInsensitiveContainsString("Hello") {
    println("TRUE")
}

ОБНОВИТЬ

Это часть Foundation Framework для iOS и Mac OS X 10.10.x и была частью 10.10 во время моей первоначальной публикации.

Создан документ: 2014-06-05 12:26:27 -0700 Замечания к выпуску OS X © Apple Inc., 2014. Все права защищены.

Замечания к выпуску OS X 10.10 Cocoa Foundation Framework

NSString теперь имеет следующие два вспомогательных метода:

- (BOOL)containsString:(NSString *)str;

- (BOOL)localizedCaseInsensitiveContainsString:(NSString *)str;


1
Имейте в виду, что этот подход требует iOS 8.
Эндрю Эблинг

9

Вот мой первый удар в этом на быстрой площадке. Я расширяю String, предоставляя две новые функции (contains и containsIgnoreCase)

extension String {
    func contains(other: String) -> Bool{
        var start = startIndex

        do{
            var subString = self[Range(start: start++, end: endIndex)]
            if subString.hasPrefix(other){
                return true
            }

        }while start != endIndex

        return false
    }

    func containsIgnoreCase(other: String) -> Bool{
        var start = startIndex

        do{
            var subString = self[Range(start: start++, end: endIndex)].lowercaseString
            if subString.hasPrefix(other.lowercaseString){
                return true
            }

        }while start != endIndex

        return false
    }
}

Используйте это так

var sentence = "This is a test sentence"
sentence.contains("this")  //returns false
sentence.contains("This")  //returns true
sentence.containsIgnoreCase("this")  //returns true

"This is another test sentence".contains(" test ")    //returns true

Буду рад любым отзывам :)


Следующий шаг: Сделайте это универсальной функцией, которая работает со всеми коллекциями :-) Например, проверьте встроенную функцию StartWith (). В варианте «игнорировать регистр» строчные строки нужно вводить только один раз (пусть lc = other.lowercaseString перед do)
hnh

9

Из всех ответов здесь, я думаю, что они либо не работают, либо немного взломаны (возвращаясь к NSString). Весьма вероятно, что правильный ответ на этот вопрос изменился в разных бета-версиях.

Вот что я использую:

let string: String = "hello Swift"
if string.rangeOfString("Swift") != nil
{
    println("exists")
}

"! = Nil" стал обязательным в бета-версии 5.


6

Вот ты где:

let s = "hello Swift"
if let textRange = s.rangeOfString("Swift") {
    NSLog("exists")
}

Иногда вам может понадобиться компактная форма следующим образом: let rangeIfExists = string.rangeOfString ("Swift") ?? false, который либо возвращает false как логическое значение, если оно не содержится, либо NSRange в противном случае
Стефан де Лука

5

Вам не нужно писать какой-либо специальный код для этого. Начиная с версии 1.2 в Swift уже есть все необходимые методы:

  • Длина строки: count(string);
  • проверки , если строка содержит подстроку: contains(string, substring);
  • проверка, начинается ли строка с подстроки: startsWith(string, substring)
  • и так далее.

Swift 2 не то же самое.
Сурагч

2
Swift 2 : string.hasPrefix («начало»)
SwiftArchitect


4

Ну вот! Готов к Xcode 8 и Swift 3.

import UIKit

let mString = "This is a String that contains something to search."
let stringToSearchUpperCase = "String"
let stringToSearchLowerCase = "string"

mString.contains(stringToSearchUpperCase) //true
mString.contains(stringToSearchLowerCase) //false
mString.lowercased().contains(stringToSearchUpperCase) //false
mString.lowercased().contains(stringToSearchLowerCase) //true

3

string.containsString доступен только в 10.10 Yosemite (и, вероятно, iOS8). Также соединение с ObjectiveC дает сбой в 10.9. Вы пытаетесь передать NSString в NSCFString. Я не знаю разницы, но я могу сказать 10.9 barfs, когда он выполняет этот код в приложении OS X 10.9.

Вот различия в Swift с 10.9 и 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/index.html containsString доступен только в 10.10

Диапазон String выше отлично работает на 10,9. Я считаю, что разработка на 10.9 супер стабильна с Xcode beta2. Я не использую игровые площадки или игровую версию командной строки. Я нахожу, что если импортированы правильные рамки, автозаполнение очень полезно.


3

С новым синтаксисом в Swift 4 вы можете просто

string.contains("Swift 4 is the best")

строка ваша строковая переменная


2

Версия Xcode 8 / Swift 3:

let string = "hello Swift"

if let range = string.range(of: "Swift") {
    print("exists at range \(range)")
} else {
    print("does not exist")
}

if let lowercaseRange = string.lowercased().range(of: "swift") {
    print("exists at range \(lowercaseRange)")
} else {
    print("does not exist")
}

Вы также можете использовать contains:

string.contains("swift") // false
string.contains("Swift") // true

2

Проверьте, содержит ли он «Привет»

let s = "Hello World"

if s.rangeOfString("Hello") != nil {
    print("Yes it contains 'Hello'")
}

2

Swift 4 способа проверить наличие подстрок, включая необходимый Foundation(или UIKit) каркас импорта:

import Foundation // or UIKit

let str = "Oh Canada!"

str.contains("Can") // returns true

str.contains("can") // returns false

str.lowercased().contains("can") // case-insensitive, returns true

Если Foundation(или UIKit) фреймворк не импортирован, str.contains("Can")выдаст ошибку компилятора.


Этот ответ является регургитирующим ответом manojlds , который является полностью правильным. Я понятия не имею , почему так много ответов пройти через столько хлопот , чтобы воссоздать Foundation«s String.contains(subString: String)метод.


1
// Search string exist in employee name finding.
var empName:NSString! = employeeDetails[filterKeyString] as NSString

Case sensitve search.
let rangeOfSearchString:NSRange! = empName.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch)

// Not found.
if rangeOfSearchString.location != Foundation.NSNotFound
{
    // search string not found in employee name.
}
// Found
else
{
    // search string found in employee name.
}

1

Свифт 3: Здесь вы можете увидеть мое умное расширение для поиска строки, которое позволяет вам выполнять поиск по строке, чтобы узнать, содержит ли она, или, возможно, отфильтровать коллекцию на основе текста поиска.

https://github.com/magonicolas/Swift-Smart-String-Search


0

В iOS 8 и новее вы можете использовать эти два NSStringметода:

@availability(iOS, introduced=8.0)
func containsString(aString: String) -> Bool

@availability(iOS, introduced=8.0)
func localizedCaseInsensitiveContainsString(aString: String) -> Bool

Какая? похоже, его нет в наличии? в версии, которая поставляется с xcode 6.1
Ali

0

Я нашел пару интересных вариантов использования. Эти варианты используют метод rangeOfString, и я включаю пример равенства, чтобы показать, как лучше всего использовать функции поиска и сравнения строк в Swift 2.0.

//In viewDidLoad() I assign the current object description (A Swift String) to self.loadedObjectDescription
self.loadedObjectDescription = self.myObject!.description

Позже, после внесения изменений в self.myObject, я могу обратиться к следующим подпрограммам сравнения строк (настройка как ленивые переменные, которые возвращают Bool). Это позволяет проверить состояние в любое время.

lazy var objectHasChanges : Bool = {
        guard self.myObject != nil else { return false }
        return !(self.loadedObjectDescription == self.myObject!.description)
    }()

Вариант этого происходит, когда иногда мне нужно проанализировать отсутствующее свойство для этого объекта. Поиск строки позволяет мне найти конкретную подстроку, которая имеет значение nil (по умолчанию при создании объекта).

    lazy var isMissingProperty : Bool = {
        guard self.myObject != nil else { return true }
        let emptyPropertyValue = "myProperty = nil"
        return (self.myObject!.description.rangeOfString(emptyPropertyValue) != nil) ? true : false
    }()

0

Если вы хотите проверить, что одна строка содержит в себе другую подстроку или нет, вы также можете проверить это так,

var name = String()  
name = "John has two apples." 

Теперь, в этой конкретной строке, если вы хотите знать, содержит ли она фруктовое название «яблоко» или нет, вы можете сделать,

if name.contains("apple")      
{  
print("Yes , it contains fruit name")    
}    
else      
{    
 print(it does not contain any fruit name)    
}    

Надеюсь, что это работает для вас.


-2

Вы можете просто сделать то, что вы упомянули:

import Foundation
...
string.contains("Swift");

Из документов:

StringТип Swift легко связан с NSString классом Foundation . Если вы работаете с платформой Foundation в Cocoa или Cocoa Touch, весь NSStringAPI доступен для вызова любого Stringзначения, которое вы создаете, в дополнение к функциям String, описанным в этой главе. Вы также можете использовать значение String с любым API, для которого требуется экземпляр NSString.

Вам необходимо import Foundationсвязать NSStringметоды и сделать их доступными для класса Swift String.


Не я, но нет, это не так.
Цезарь

Ага. Пробовал на игровой площадке, в приложении Mac и в приложении iOS. Также пробовал в Playground импортировать Какао, UIKit, Foundation и все возможные комбинации трех из них (кроме Какао / UIKit, что не имеет смысла)
Цезарь

Это больше не относится к Swift 1.2
Кельвин Лау

-4

SWIFT 4 - это очень просто!

if (yourString.contains("anyThing")) {
   Print("Exist")
}

1
Чем это отличается от некоторых других ответов здесь?
Эшли Миллс

1
$ swift Welcome to Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1). Type :help for assistance. 1> print ("Ping") Ping 2> Print ("Ping") error: repl.swift:2:1: error: use of unresolved identifier 'Print' Print ("Ping") ^~~~~ Предоставляя непроверенный ответ, который не работает. Печать! = Печать.
Фред Ганнетт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.