Come posso verificare se una stringa contiene un'altra stringa in Swift?


535

Nel Objective-Ccodice per verificare la presenza di una sottostringa in un NSStringè:

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

Ma come posso farlo in Swift?


2
@rckoenes Sono nuovo su veloce, so come fare questo obiettivoC
Rajneesh071

1
Allora perché non avviare un parco giochi e provarlo.
rckoenes,

Se sei ancora in giro, cambia la risposta accettata a quella dell'utente1021430 ... è corretta
Dan Rosenstark,

Risposte:


1044

Puoi fare esattamente la stessa chiamata con Swift:

Swift 4 e Swift 5

In Swift 4 String è un insieme di Charactervalori, non è stato così in Swift 2 e 3, quindi puoi usare questo codice più conciso 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 più vecchio

var string = "hello Swift"

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

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

Spero che questa sia una soluzione utile poiché alcune persone, incluso me, hanno incontrato alcuni strani problemi chiamando containsString(). 1

PS. Non dimenticare diimport Foundation

Le note

  1. Ricorda solo che l'uso delle funzioni di raccolta su Stringhe ha alcuni casi limite che possono darti risultati inaspettati, ad esempio quando hai a che fare con emoji o altri gruppi di grafi come lettere accentate.

13
La documentazione di Apple dice: 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 (@"").Quindi forse solo il controllo per nilnon funzionerà correttamente.
Alex,

7
string.lowercaseString.rangeOfString ("swift"). location! = NSNotFound. Si prega di leggere la documentazione .. non verrà restituito un oggetto nullo.
TheCodingArt

4
@TheGamingArt Sì, lo farai. Rapidi viaggi di andata e ritorno tutto per te in modo automatico, in modo che se NSRange {NSNotFound, 0}è rappresentato per te come zero. Se si tratta di un intervallo effettivo, viene rappresentato per te come intervallo rapido (opzionale). Freddo.
opaco,

4
Grr. contieneString non è nei documenti, nemmeno da Xcode 6.3.1.
Duncan C,

19
@TheGoonie: Questo non chiama NSString'il .rangeOfString(). Questo sta chiamando Strings' .rangeOfString(), che è dichiarata comefunc rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
newacct

192

Modo di estensione

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

Generalmente Swift 4 contiene un metodo, tuttavia è disponibile da iOS 8.0+


Swift 3.1

Puoi scrivere l'estensione contains:e containsIgnoringCaseperString

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

Versione Swift precedente

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

Esempio:

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
per ignorare il caso usare return self.rangeOfString (trova, opzioni: NSStringCompareOptions.CaseInsensitiveSearch)! = nil
masgar

1
Non è più necessario a meno che tu non abbia in Foundationgiro ... containsStringfunziona bene.
Dan Rosenstark,

5
per rapido 3.0. Cambia in basso: extension String {func contiene (trova: String) -> Bool {return self.range (of: find)! = Nil} func IncludesIgnoringCase (find: String) -> Bool {return self.range (of: find , opzioni: .caseInsensitive)! = nil}}
Michael Shang,

Per Swift 4 -> extension String {func contiene (trova: String) -> Bool {return self.range (di: trova)! = Nil} func IncludesIgnoringCase (find: String) -> Bool {return self.range (of: trova, opzioni: .caseInsensitive)! = nil}}
shokaveli,

50

Dai documenti, sembra che la chiamata containsString()a una stringa dovrebbe funzionare:

Il tipo String di Swift è collegato in modo uniforme alla classe NSString di Foundation. Se stai lavorando con il framework Foundation in Cocoa o Cocoa Touch, l'intera API NSString è disponibile per chiamare qualsiasi valore String creato, oltre alle funzionalità String descritte in questo capitolo. Puoi anche utilizzare un valore String con qualsiasi API che richiede un'istanza NSString.

Tuttavia, non sembra funzionare in questo modo.

Se si tenta di utilizzare someString.containsString(anotherString), verrà visualizzato un errore di compilazione che indica 'String' does not contain a member named 'containsString'.

Quindi, ti rimangono alcune opzioni, una delle quali è quella di collegare esplicitamente il tuo Stringa Objective-C usando bridgeToObjectiveC()altri due che implicano esplicitamente l'uso di un NSStringe quello finale implica il cast Stringdi unNSString

Collegando, otterrai:

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

Digitando esplicitamente la stringa come an NSString, otterrai:

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

Se ne hai uno esistente String, puoi inizializzare un NSString usando NSString (stringa :):

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

E infine, puoi lanciare un esistente Stringin uno NSStringcome di seguito

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

4
L'ultimo esempio (non ne ho provato altri) si arresta in modo anomalo su iOS 7 (dispositivo); Le app Swift dovrebbero funzionare perfettamente su iOS 7. L'errore che ottengo è [__NSCFString containsString:]: unrecognized selector sent to instance. Inoltre, non riesco a trovare il metodo containsStringnei documenti di sviluppo per confermare se è nuovo per iOS 8.
Jason Leach,

Interessante. L'ho provato solo su un parco giochi. Ci proverò più tardi quando sono sul mio computer.
Cezar,

la terza e la quarta opzione sono le uniche consentite dal compilatore. entrambi si bloccano per me in beta 4 in iOS 7.
palmi

38

Un altro. Supporta opzioni case e diacritiche.

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

uso

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

iOS 9+

Funzione insensibile ai casi e ai segni diacritici disponibile da iOS 9.

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

31

A partire da Xcode 7.1 e Swift 2.1 containsString()funziona bene per me.

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

Swift 4:

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

E un esempio insensibile a Swift 4:

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

O usando Stringun'estensione senza distinzione tra maiuscole e minuscole :

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
è necessario import Foundation, altrimenti non funzionerà.
Andrii Chernenko,

Uno import UIKitdei due import Foundationè richiesto, almeno con iOS 11 e Swift 4.
Murray Sagal,

Ma questo è case sensitive. Come si fa il confronto ignorando il caso. Come in Java String.equalsIgnoreCase (anotherString)?
Zulkarnain Shah,

@zulkarnainshah Ho aggiunto un esempio alla risposta.
Murray Sagal,

@MurraySagal Non si tratta ancora di ricerca senza distinzione tra maiuscole e minuscole. Stai convertendo la stringa originale in minuscolo e poi confrontandola esplicitamente con una stringa in minuscolo. Farà il lavoro, ma non è questo il modo ideale per farlo
zulkarnain shah

22

In Swift 4.2

Uso

func contains(_ str: String) -> Bool

Esempio

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

4
Si noti che ciò richiede l'importazione di Foundation.
rmaddy,

16

> IN SWIFT 3.0

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

Produzione

String Contains Another String

15

Puoi farlo molto facilmente in Swift usando il codice:

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

10

Solo un addendum alle risposte qui.

Puoi anche eseguire un test insensibile al maiuscolo locale usando:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

Esempio:

    import Foundation

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

AGGIORNARE

Questo fa parte del Foundation Framework per iOS e Mac OS X 10.10.x e faceva parte del 10.10 al momento della mia pubblicazione originale.

Documento generato: 2014-06-05 12:26:27 -0700 Note sulla versione di OS X Copyright © 2014 Apple Inc. Tutti i diritti riservati.

Note di rilascio di OS X 10.10 Cocoa Foundation Framework

NSString ora ha i seguenti due metodi di convenienza:

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

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


1
Tieni presente che questo approccio richiede iOS 8.
Andrew Ebling,

9

Ecco la mia prima pugnalata a questo nel rapido parco giochi. Estendo String fornendo due nuove funzioni (contiene e contieneIgnoreCase)

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

Usalo in questo modo

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

Gradirei qualsiasi feedback :)


Prossimo passo: rendi questa una funzione generica che funziona su tutte le collezioni :-) Ad esempio, controlla la funzione integrata di startWith (). Nella variante 'ignora case', metti una sola volta in minuscolo le stringhe (let lc = other.lowercaseString before the do)
hnh

9

Di tutte le risposte qui, penso che o non funzionino, o sono un po 'un hack (ritornando a NSString). È molto probabile che la risposta corretta sia cambiata con le diverse versioni beta.

Ecco cosa uso:

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

"! = Zero" è diventato necessario con Beta 5.


6

Ecco qui:

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

A volte potresti aver bisogno di un modulo compatto come segue: let rangeIfExists = string.rangeOfString ("Swift") ?? false che restituisce false come booleano se non è contenuto o NSRange altrimenti
Stéphane de Luca

5

Non è necessario scrivere alcun codice personalizzato per questo. A partire dalla versione 1.2 Swift ha già avuto tutti i metodi necessari:

  • ottenendo lunghezza della stringa: count(string);
  • controllare se la stringa contiene sottostringa: contains(string, substring);
  • verifica se la stringa inizia con la sottostringa: startsWith(string, substring)
  • e così via.

Swift 2 non è lo stesso.
Suragch,

2
Swift 2 : string.hasPrefix ("start")
SwiftArchitect

5

In Swift 3

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

4

Ecco qui! Pronto per Xcode 8 e 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 è disponibile solo in Yosemite 10.10 (e probabilmente iOS8). Inoltre, collegandolo agli crash di ObjectiveC in 10.9. Stai provando a passare un NSString a NSCFString. Non conosco la differenza, ma posso dire 10.9 barfs quando esegue questo codice in un'app OS X 10.9.

Ecco le differenze in Swift con 10.9 e 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/index.html contieneString è disponibile solo in 10.10

La gamma di stringhe sopra funziona alla grande su 10.9. Sto scoprendo che lo sviluppo su 10.9 è super stabile con Xcode beta2. Non utilizzo i campi da gioco attraverso o la versione da riga di comando dei campi da gioco. Sto scoprendo che se vengono importati i framework corretti, il completamento automatico è molto utile.


3

Con e la nuova sintassi in swift 4 puoi semplicemente

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

string è la tua variabile di stringa


2

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

Puoi anche usare contains:

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

2

Controlla se contiene "Hello"

let s = "Hello World"

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

2

Swift 4 modi per verificare la presenza di sottostringhe, inclusa l' importazione del framework necessaria Foundation(o 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

A meno che non venga importato Foundation(o UIKit) il framework, str.contains("Can")verrà generato un errore del compilatore.


Questa risposta rigurgita la risposta di Manojlds , che è completamente corretta. Non ho idea del perché così tante risposte attraversino così tanti problemi per ricreare Foundationil String.contains(subString: String)metodo.


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


0

In iOS 8 e versioni successive, puoi utilizzare questi due NSStringmetodi:

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

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

Che cosa? sembra che non sia disponibile? nella versione fornita con xcode 6.1
Ali

0

Ho trovato un paio di casi d'uso interessanti. Queste varianti fanno uso del metodo rangeOfString e includo l'esempio di uguaglianza per mostrare come si potrebbe usare al meglio le funzionalità di ricerca e confronto di Stringhe in Swift 2.0

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

Più tardi, dopo aver apportato modifiche a self.myObject, posso fare riferimento alle seguenti routine di confronto delle stringhe (impostazione come variabili pigre che restituiscono un valore booleano). Ciò consente di controllare lo stato in qualsiasi momento.

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

Una variante di ciò accade quando a volte ho bisogno di analizzare una proprietà mancante su quell'oggetto. Una ricerca di stringhe mi consente di trovare una particolare sottostringa impostata su zero (impostazione predefinita quando viene creato un oggetto).

    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

Se vuoi verificare che una stringa contenga un'altra sottostringa al suo interno o no, puoi controllarla anche in questo modo,

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

Ora, in questa stringa particolare se vuoi sapere se contiene il nome della frutta "mela" o no, puoi farlo,

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

Spero che questo funzioni per te.


-2

Puoi semplicemente fare quello che hai menzionato:

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

Dai documenti:

Il Stringtipo di Swift si collega perfettamente alla NSString classe della Fondazione . Se stai lavorando con il framework Foundation in Cocoa o Cocoa Touch, l'intera NSStringAPI è disponibile per chiamare qualsiasi Stringvalore che crei, oltre alle funzionalità String descritte in questo capitolo. Puoi anche utilizzare un valore String con qualsiasi API che richiede un'istanza NSString.

Devi import Foundationcollegare i NSStringmetodi e renderli disponibili alla classe String di Swift.


Non io, ma no, non lo è.
Cezar,

Sì. Ho provato in un parco giochi, in un'app per Mac e in un'app per iOS. Provato anche in Playground importando Cocoa, UIKit, Foundation e tutte le possibili combinazioni dei tre (tranne Cocoa / UIKit, che non ha senso)
Cezar

Questo non è più il caso di Swift 1.2
Kelvin Lau,

-4

SWIFT 4 è molto semplice !!

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

1
In che modo questo differisce da molte delle altre risposte qui?
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") ^~~~~ Fornendo una risposta non testata che non funziona. Stampa! = Stampa.
Fred Gannett,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.