web-dev-qa-db-fra.com

Comment vérifier si une chaîne contient une autre chaîne dans Swift?

Dans Objective-C, le code permettant de rechercher une sous-chaîne dans une NSString est: 

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

Mais comment puis-je faire cela dans Swift?

450
Rajneesh071

Vous pouvez faire exactement le même appel avec Swift:

Swift 4

Dans Swift 4, String est une collection de valeurs Character. Ce n'est pas comme cela dans Swift 2 et 3, vous pouvez donc utiliser ce code plus concis.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")
}

Swift plus âgé

var string = "hello Swift"

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

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

J'espère que c'est une solution utile, car certaines personnes, y compris moi-même, ont rencontré des problèmes étranges en appelant containsString().1

PS. N'oubliez pas de import Foundation

Notes de bas de page

  1. Rappelez-vous simplement que l’utilisation des fonctions de collection sur Strings a quelques cas Edge qui peuvent vous donner des résultats inattendus, e. g. lorsqu'il s'agit d'emojis ou d'autres grappes de graphèmes comme des lettres accentuées.
872
Jens Wirth

Voie d'extension

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

Généralement, Swift 4 a contient méthode, mais disponible depuis iOS 8.0+


Swift 3.1

Vous pouvez écrire les extensions contains: et containsIgnoringCase pour 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 
   }
 }

Ancienne version 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
     }
}

Exemple:

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
182
Maxim Shoustin

D'après les documents, il semble que l'appel de containsString() sur une chaîne devrait fonctionner:

Le type de chaîne de Swift est relié de manière transparente à la chaîne NSString de la Fondation classe. Si vous travaillez avec le framework Foundation dans Cocoa ou Cocoa Touch, l’ensemble de l’API NSString est disponible pour faire appel à n’importe quel Valeur de chaîne que vous créez, en plus des fonctionnalités de chaîne décrites dans ce chapitre. Vous pouvez également utiliser une valeur String avec n’importe quelle API prenant en charge nécessite une instance NSString.

Cependant, cela ne semble pas fonctionner de cette façon.

Si vous essayez d'utiliser someString.containsString(anotherString), vous obtiendrez une erreur de compilation qui indique 'String' does not contain a member named 'containsString'.

Donc, il ne vous reste que quelques options dont l’une est de relier explicitement votre String à Objective-C en utilisant bridgeToObjectiveC(), deux autres impliquent explicitement l’utilisation de NSString et la dernière consiste à convertir String en NSString

En établissant un pont, vous obtiendrez:

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

En tapant explicitement la chaîne en tant que NSString, vous obtiendrez:

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

Si vous avez une String existante, vous pouvez initialiser une chaîne NSString à l'aide de NSString (chaîne :):

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

Et enfin, vous pouvez transtyper une String existante en une NSString comme ci-dessous

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

Un autre. Prend en charge les options de cas et diacritiques.

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
  }
}

Usage

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

iOS 9+

Fonction insensible à la casse et aux signes diacritiques disponible depuis iOS 9.

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

À partir de Xcode 7.1 et Swift 2.1, containsString() fonctionne correctement pour moi.

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

Swift 4: 

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

Et un exemple de Swift 4 insensible à la casse: 

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

Ou en utilisant une extension String insensible à la casse:

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
31
Murray Sagal

Dans Swift 4.2

Utilisation

func contains(_ str: String) -> Bool

Exemple

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

> IN Swift 3.0

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

Sortie

String Contains Another String
16
Ashok R

Vous pouvez le faire très facilement dans Swift en utilisant le code:

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

Parmi toutes les réponses proposées, je pense qu’elles ne fonctionnent pas ou sont un peu un bidouillage (renvoi à NSString). Il est très probable que la réponse correcte à cette situation a changé avec les différentes versions bêta.

Voici ce que j'utilise:

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

Le "! = Nil" est devenu obligatoire avec Beta 5.

9
user1021430

Voici ma première incursion dans le terrain de jeu Swift . J'étend String en fournissant deux nouvelles fonctions (contient et contientIgnoreCase)

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
    }
}

Utilisez-le comme ça

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

Je serais heureux de recevoir vos commentaires :)

8
Ken

Vous voilà:

let s = "hello Swift"
if let textRange = s.rangeOfString("Swift") {
    NSLog("exists")
}
6
Stéphane de Luca

Dans Swift 3

if((a.range(of: b!, options: String.CompareOptions.caseInsensitive, range: nil, locale: nil)) != nil){
    print("Done")
}
5
Marie Amida

Vous n'avez pas besoin d'écrire de code personnalisé pour cela. Depuis la version 1.2, Swift dispose déjà de toutes les méthodes dont vous avez besoin:

  • obtenir la longueur de la chaîne: count(string);
  • vérifier si la chaîne contient une sous-chaîne: contains(string, substring);
  • vérifier si la chaîne commence par la sous-chaîne: startsWith(string, substring)
  • et etc.
5
Max Ivashkevich

Voici! Prêt pour Xcode 8 et 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
4
Carlitos

Vérifiez s'il contient 'Bonjour'

let s = "Hello World"

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

Swift 4 moyen de vérifier les sous-chaînes, y compris l'importation nécessaire de la structure Foundation (ou 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

Si le cadre Foundation (ou UIKit) n'est pas importé, str.contains("Can") donnera une erreur de compilation.


Cette réponse régurgite réponse de manojlds , ce qui est tout à fait correct. Je ne sais pas pourquoi tant de réponses rencontrent tant de difficultés pour recréer la méthode Foundation de String.contains(subString: String).

2
NonCreature0714

Version 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")
}

Vous pouvez également utiliser contains:

string.contains("Swift") // false
string.contains("Swift") // true
2
JAL
// 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
abhi

Si vous voulez vérifier qu'une chaîne contient ou non une autre sous-chaîne, vous pouvez aussi la vérifier comme ceci:

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

Maintenant, dans cette chaîne particulière si vous voulez savoir si elle contient le nom du fruit 'Apple' ou pas, vous pouvez le faire,

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

J'espère que cela fonctionne pour toi.

0
Varsha Shivhare

J'ai trouvé quelques cas d'utilisation intéressants. Ces variantes utilisent la méthode rangeOfString et j'inclus l'exemple d'égalité pour montrer comment utiliser au mieux les fonctionnalités de recherche et de comparaison de Strings dans Swift 2.0

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

Plus tard, après avoir apporté des modifications à self.myObject, je peux me référer au routines de comparaison de chaînes suivantes (configuration sous forme de variables lazy qui renvoient un booléen). Cela permet de vérifier l'état à tout moment.

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

Une variante de cela se produit lorsque j'ai parfois besoin d'analyser un manquant propriété sur cet objet. Une recherche de chaîne me permet de trouver un la sous-chaîne particulière étant définie sur nil (valeur par défaut lors de la création d'un objet).

    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
Tommie C.

Swift 3: Ici, vous pouvez voir mon extension de recherche intelligente d’une chaîne qui vous permet de faire une recherche sur une chaîne pour voir si elle contient, ou peut-être de filtrer une collection en fonction d’un texte de recherche.

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

0

Dans iOS 8 et versions ultérieures, vous pouvez utiliser ces deux méthodes NSString:

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

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