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

535

Dans Objective-Cle code pour vérifier une sous-chaîne dans un NSStringest:

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

Mais comment faire cela dans Swift?

Rajneesh071
la source
2
@rckoenes Je suis nouveau sur swift, je sais comment faire cet objectifC
Rajneesh071
1
Alors pourquoi ne pas simplement commencer une aire de jeux et l'essayer.
rckoenes
Si vous êtes toujours là, veuillez changer la réponse acceptée par celle de user1021430 ... c'est correct
Dan Rosenstark

Réponses:

1045

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

Swift 4 et Swift 5

Dans Swift 4, String est une collection de Charactervaleurs, ce n'était pas comme ça dans Swift 2 et 3, vous pouvez donc utiliser ce code 1 plus concis :

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, dont moi, ont rencontré d'étranges problèmes en appelant containsString(). 1

PS. N'oubliez pasimport Foundation

Notes de bas de page

  1. N'oubliez pas que l'utilisation des fonctions de collecte sur les chaînes a des cas marginaux qui peuvent vous donner des résultats inattendus, par exemple lorsque vous utilisez des emojis ou d'autres grappes de graphèmes comme des lettres accentuées.
Jens Wirth
la source
13
La documentation d'Apple dit: 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 (@"").Alors peut-être que la simple vérification nilne fonctionnera pas correctement.
Alex
7
string.lowercaseString.rangeOfString ("swift"). location! = NSNotFound. Veuillez lire la documentation .. vous ne récupérerez aucun objet nul.
TheCodingArt
4
@TheGamingArt Oui, vous le ferez. Swift va-et-vient le tout pour vous de manière automatique, de sorte que si le NSRange est, {NSNotFound, 0}il est représenté pour vous comme nul. S'il s'agit d'une plage réelle, elle est représentée pour vous sous la forme d'une plage Swift (facultative). Cool.
mat
4
Grr. containsString n'est pas dans la documentation, même à partir de Xcode 6.3.1.
Duncan C
19
@TheGoonie: Ce n'appelle NSString« s .rangeOfString(). Ceci appelle String's .rangeOfString(), qui est déclaré commefunc rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
newacct
192

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 contient une méthode, mais elle est disponible à partir d'iOS 8.0+


Swift 3.1

Vous pouvez écrire l'extension contains:et containsIgnoringCasepourString

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
Maxim Shoustin
la source
6
pour ignorer la casse, utilisez return self.rangeOfString (find, options: NSStringCompareOptions.CaseInsensitiveSearch)! = nil
masgar
1
Ce n'est plus nécessaire à moins que vous n'en ayez pas Foundationautour ... ça containsStringmarche bien.
Dan Rosenstark
5
pour swift 3.0. Passez à ci-dessous: 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}}
Michael Shang
Pour Swift 4 -> l'extension String {func contient (find: String) -> Bool {return self.range (of: find)! = Nil} func containsIgnoringCase (find: String) -> Bool {return self.range (of: find, options: .caseInsensitive)! = nil}}
shokaveli
50

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

Le type String de Swift est ponté de manière transparente à la classe NSString de Foundation. Si vous travaillez avec le framework Foundation dans Cocoa ou Cocoa Touch, l'intégralité de l'API NSString est disponible pour appeler toute 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 qui 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 temps de compilation qui indique 'String' does not contain a member named 'containsString'.

Donc, il vous reste quelques options, dont l'une consiste à relier explicitement votre Stringà Objective-C en utilisant les bridgeToObjectiveC()deux autres impliquent l'utilisation explicite d'un NSStringet la dernière implique de lancer le Stringvers unNSString

En créant un pont, vous obtiendriez:

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

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

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

Si vous en avez un String, vous pouvez initialiser une NSString à partir de celle-ci en utilisant NSString (string :):

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

Et enfin, vous pouvez convertir un existant Stringen un NSStringcomme ci-dessous

var string = "hello Swift"
if (string as NSString).containsString("Swift") {
    println("YES")
}
Cezar
la source
4
Le dernier exemple (je n'ai pas essayé d'autres) se bloque pour moi sur iOS 7 (appareil); Les applications Swift devraient fonctionner correctement sur iOS 7. L'erreur que j'obtiens est [__NSCFString containsString:]: unrecognized selector sent to instance. De plus, je ne trouve pas la méthode containsStringdans les documents de développement pour confirmer si c'est nouveau pour iOS 8.
Jason Leach
Intéressant. Je n'ai testé cela que sur un terrain de jeu. J'essaierai plus tard lorsque je serai sur mon ordinateur.
Cezar
les troisième et quatrième options sont les seules autorisées par le compilateur. les deux se bloquent pour moi en version bêta 4 dans iOS 7.
palmi
38

Un autre. Prend en charge les options de casse 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
}
Evgenii
la source
31

Depuis Xcode 7.1 et Swift 2.1 containsString()fonctionne bien 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 Swift 4 insensible à la casse:

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

Ou en utilisant une Stringextension 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
Murray Sagal
la source
3
vous devez import Foundation, sinon cela ne fonctionnera pas.
Andrii Chernenko
Soit import UIKitde import Foundationest nécessaire, au moins avec iOS 11 et Swift 4.
Murray Sagal
Mais c'est sensible à la casse. Comment faites-vous la comparaison tout en ignorant la casse. Comme dans java String.equalsIgnoreCase (anotherString)?
zulkarnain shah
@zulkarnainshah J'ai ajouté un exemple à la réponse.
Murray Sagal
@MurraySagal Ce n'est toujours pas une recherche insensible à la casse. Vous convertissez la chaîne d'origine en minuscules, puis vous la comparez explicitement avec une chaîne en minuscules. Cela fera le travail, mais ce n'est pas le moyen idéal de le faire
zulkarnain shah
22

Dans Swift 4.2

Utilisation

func contains(_ str: String) -> Bool

Exemple

let string = "hello Swift"
let containsSwift = string.contains("Swift")
print(containsSwift) // prints true
Saranjith
la source
4
Veuillez noter que cela nécessite que vous importiez Foundation.
rmaddy
16

> DANS SWIFT 3.0

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

Production

String Contains Another String
Ashok R
la source
15

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")}
Anmol Kukreja
la source
10

Juste un addendum aux réponses ici.

Vous pouvez également effectuer un test local insensible à la casse en utilisant:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

Exemple:

    import Foundation

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

MISE À JOUR

Cela fait partie du Framework Foundation pour iOS et Mac OS X 10.10.x et faisait partie de 10.10 au moment de ma publication d'origine.

Document généré: 2014-06-05 12:26:27 -0700 Notes de version OS X Copyright © 2014 Apple Inc. Tous droits réservés.

Notes de version OS X 10.10 Cocoa Foundation Framework

NSString dispose désormais des deux méthodes de commodité suivantes:

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

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

markhunte
la source
1
Soyez conscient que cette approche nécessite iOS 8.
Andrew Ebling
9

Voici mon premier coup de couteau à cela dans la cour de récréation rapide. J'étends 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

J'accueillerais vos commentaires :)

Ken
la source
Étape suivante: Faites-en une fonction générique qui fonctionne sur toutes les collections :-) Par exemple, vérifiez la fonction intégrée startWith (). Dans la variante "ignorer la casse", ne mettez les chaînes en minuscules qu'une seule fois (laissez lc = other.lowercaseString avant le do)
hnh
9

De toutes les réponses ici, je pense que soit elles ne fonctionnent pas, soit elles sont un peu un hack (retour à NSString). Il est très probable que la bonne réponse à cela ait 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 la version bêta 5.

user1021430
la source
6

Vous voilà:

let s = "hello Swift"
if let textRange = s.rangeOfString("Swift") {
    NSLog("exists")
}
Stéphane de Luca
la source
Parfois, vous pourriez avoir besoin d'un formulaire compact comme suit: let rangeIfExists = string.rangeOfString ("Swift") ?? false qui renvoie false comme booléen s'il n'est pas contenu ou sinon NSRange
Stéphane de Luca
5

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

  • obtenir la longueur de chaîne: count(string);
  • vérifier si la chaîne contient sous - chaîne: contains(string, substring);
  • vérifier si la chaîne commence par une sous-chaîne: startsWith(string, substring)
  • et etc.
Max Ivashkevich
la source
Swift 2 n'est pas le même.
Suragch
2
Swift 2 : string.hasPrefix ("start")
SwiftArchitect
5

Dans Swift 3

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

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
Carlitos
la source
3

string.containsString n'est disponible que dans 10.10 Yosemite (et probablement iOS8). Le pontage vers ObjectiveC se bloque dans 10.9. Vous essayez de passer une NSString à NSCFString. Je ne connais pas la différence, mais je peux dire 10,9 barfs quand il exécute ce code dans une application OS X 10.9.

Voici les différences dans Swift avec 10.9 et 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/index.html containsString n'est disponible qu'en 10.10

La plage de chaînes ci-dessus fonctionne très bien sur 10.9. Je trouve que le développement sur 10.9 est super stable avec Xcode beta2. Je n'utilise pas les terrains de jeux ou la version en ligne de commande des terrains de jeux. Je trouve que si les cadres appropriés sont importés, la saisie semi-automatique est très utile.

Bon temps
la source
3

Avec et une nouvelle syntaxe dans swift 4, vous pouvez simplement

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

chaîne est votre variable chaîne

100tomer
la source
2

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
JAL
la source
2

Vérifiez s'il contient «Bonjour»

let s = "Hello World"

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

la source
2

Swift 4 façons de vérifier les sous-chaînes, y compris l' importation de framework nécessaire 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

Sauf si Foundation(ou UIKit) le framework est importé, str.contains("Can")donnera une erreur de compilation.


Cette réponse régurgite la réponse de manojlds , qui est tout à fait correcte. Je n'ai aucune idée pourquoi tant de réponses ont tant de mal à recréer Foundationla String.contains(subString: String)méthode de.

NonCreature0714
la source
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.
}
abhi
la source
1

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

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

Mago Nicolas Palacios
la source
0

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

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

@availability(iOS, introduced=8.0)
func localizedCaseInsensitiveContainsString(aString: String) -> Bool
Rudolf Adamkovič
la source
Quelle? on dirait qu'il n'est pas disponible? dans la version fournie avec xcode 6.1
Ali
0

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 des chaînes 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 aux routines de comparaison de chaînes suivantes (configuration en tant que variables paresseuses qui renvoient un Bool). 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 une propriété manquante sur cet objet. Une recherche de chaîne me permet de trouver une sous-chaîne particulière définie sur nil (la valeur par défaut lorsqu'un objet est créé).

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

Si vous voulez vérifier qu'une chaîne contient une autre sous-chaîne ou non, vous pouvez également 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 ou non le nom du fruit, 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.

Varsha Shivhare
la source
-2

Vous pouvez simplement faire ce que vous avez mentionné:

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

De la documentation:

Le Stringtype de Swift est parfaitement intégré à la NSString classe Foundation . Si vous travaillez avec le framework Foundation dans Cocoa ou Cocoa Touch, l'intégralité de l' NSStringAPI est disponible pour appeler n'importe quelle Stringvaleur 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 qui nécessite une instance NSString.

Vous devez import Foundationrelier les NSStringméthodes et les rendre disponibles à la classe String de Swift.

manojlds
la source
Pas moi, mais non, ce n'est pas le cas.
Cezar
oui. Essayé dans une aire de jeux, dans une application Mac et dans une application iOS. Également essayé dans Playground, important Cocoa, UIKit, Foundation et toutes les combinaisons possibles des trois (sauf Cocoa / UIKit, ce qui n'a pas de sens)
Cezar
Ce n'est plus le cas depuis Swift 1.2
Kelvin Lau
-4

SWIFT 4 est très facile !!

if (yourString.contains("anyThing")) {
   Print("Exist")
}
oscar castellon
la source
1
En quoi est-ce différent de plusieurs des autres réponses ici?
Ashley Mills
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") ^~~~~ En fournissant une réponse non testée qui ne fonctionne pas. Imprimer! = Imprimer.
Fred Gannett