Wie überprüfe ich, ob eine Zeichenfolge in Swift eine andere Zeichenfolge enthält?


535

In Objective-Cdem Code, der nach einem Teilstring in einem sucht, NSStringist:

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

Aber wie mache ich das in Swift?


2
@rckoenes Ich bin neu in Swift, ich weiß, wie man dieses Ziel erreichtC
Rajneesh071

1
Dann starten Sie doch einfach einen Spielplatz und probieren ihn aus.
rckoenes

Wenn Sie noch da sind, ändern Sie bitte die akzeptierte Antwort in die von user1021430 ... es ist richtig
Dan Rosenstark

Antworten:


1044

Mit Swift können Sie genau den gleichen Anruf tätigen:

Swift 4 & Swift 5

In Swift 4 ist String eine Sammlung von CharacterWerten. In Swift 2 und 3 war dies nicht der Fall. Sie können also diesen prägnanteren Code 1 verwenden :

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

Älterer Swift

var string = "hello Swift"

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

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

Ich hoffe, dies ist eine hilfreiche Lösung, da einige Leute, einschließlich mir, durch einen Anruf auf seltsame Probleme gestoßen sind containsString(). 1

PS. Vergiss es nichtimport Foundation

Fußnoten

  1. Denken Sie daran, dass die Verwendung von Erfassungsfunktionen für Zeichenfolgen einige Randfälle aufweist, die zu unerwarteten Ergebnissen führen können, z. B. beim Umgang mit Emojis oder anderen Graphemclustern wie Buchstaben mit Akzent.

13
In der Dokumentation von Apple heißt es: 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 (@"").Vielleicht nilfunktioniert es nicht richtig, nur nach zu suchen.
Alex

7
string.lowercaseString.rangeOfString ("swift"). location! = NSNotFound. Bitte lesen Sie die Dokumentation. Sie erhalten kein Objekt zurück.
TheCodingArt

4
@TheGamingArt Ja, das wirst du. Schnelle Roundtrips machen das Ganze für Sie automatisch, so dass, wenn der NSRange ist, {NSNotFound, 0}er für Sie als Null dargestellt wird. Wenn es sich um einen tatsächlichen Bereich handelt, wird er für Sie als schneller Bereich dargestellt (optional). Cool.
Matt

4
Grr. enthältString ist nicht in den Dokumenten enthalten, auch nicht ab Xcode 6.3.1.
Duncan C

19
@TheGoonie: Dies ruft nicht NSStringist .rangeOfString(). Dies ruft String's .rangeOfString(), was alsfunc rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
newacct

192

Verlängerungsweg

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

Im Allgemeinen enthält Swift 4 eine Methode, die jedoch ab iOS 8.0+ verfügbar ist


Swift 3.1

Sie können Erweiterung contains:und containsIgnoringCasefür schreibenString

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

Ältere Swift-Version

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

Beispiel:

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
Um Groß- und Kleinschreibung zu ignorieren, geben Sie self.rangeOfString zurück (find, options: NSStringCompareOptions.CaseInsensitiveSearch)! = nil
masgar

1
Nicht mehr notwendig, es sei denn, Sie haben nicht in der FoundationNähe ... containsStringfunktioniert gut.
Dan Rosenstark

5
für schnelle 3.0. Wechseln Sie zu unten: Erweiterung String {func enthält (find: String) -> Bool {return self.range (von: find)! = Nil} func enthältIgnoringCase (find: String) -> Bool {return self.range (von: find , Optionen: .caseInsensitive)! = nil}}
Michael Shang

Für Swift 4 -> Erweiterung String {func enthält (find: String) -> Bool {return self.range (von: find)! = Nil} func enthältIgnoringCase (find: String) -> Bool {return self.range (von: find, options: .caseInsensitive)! = nil}}
shokaveli

50

Aus den Dokumenten geht hervor, dass das Aufrufen containsString()eines Strings funktionieren sollte:

Der String-Typ von Swift wird nahtlos mit der NSString-Klasse von Foundation verbunden. Wenn Sie mit dem Foundation-Framework in Cocoa oder Cocoa Touch arbeiten, kann die gesamte NSString-API zusätzlich zu den in diesem Kapitel beschriebenen String-Funktionen jeden von Ihnen erstellten String-Wert aufrufen. Sie können einen String-Wert auch für jede API verwenden, für die eine NSString-Instanz erforderlich ist.

Es scheint jedoch nicht so zu funktionieren.

Wenn Sie versuchen, zu verwenden someString.containsString(anotherString), wird ein Fehler bei der Kompilierung angezeigt, der besagt 'String' does not contain a member named 'containsString'.

Sie haben also nur noch einige Optionen, von denen eine darin besteht, Ihre Verbindung Stringzu Objective-C explizit zu überbrücken , indem Sie bridgeToObjectiveC()zwei andere verwenden. Dabei wird explizit eine verwendet, NSStringund bei der letzten Option wird die Option Stringin eine umgewandeltNSString

Durch Überbrücken erhalten Sie:

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

Wenn Sie die Zeichenfolge explizit als eingeben NSString, erhalten Sie:

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

Wenn Sie einen vorhandenen haben String, können Sie einen NSString mit NSString (Zeichenfolge :) daraus initialisieren:

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

Und schließlich können Sie eine vorhandene Stringin eine NSStringwie unten umwandeln

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

4
Das letzte Beispiel (ich habe andere nicht ausprobiert) stürzt für mich unter iOS 7 (Gerät) ab. Swift Apps sollten unter iOS 7 einwandfrei funktionieren. Der Fehler, den ich bekomme, ist [__NSCFString containsString:]: unrecognized selector sent to instance. Außerdem kann ich die Methode containsStringin den Entwicklungsdokumenten nicht finden , um zu bestätigen, ob sie für iOS 8 neu ist.
Jason Leach

Interessant. Ich habe das nur auf einem Spielplatz getestet. Ich werde es später versuchen, wenn ich auf meinem Computer bin.
Cezar

Die dritte und vierte Option sind die einzigen, die der Compiler zulässt. beide stürzen für mich in Beta 4 in iOS 7 ab.
Palmi

38

Noch einer. Unterstützt Fall- und diakritische Optionen.

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

Verwendungszweck

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

iOS 9+

Groß- und Kleinschreibung und diakritisch unempfindliche Funktion seit iOS 9 verfügbar.

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

31

Ab Xcode 7.1 und Swift 2.1 containsString()funktioniert das für mich einwandfrei.

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

Swift 4:

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

Und ein Swift 4-Beispiel ohne Berücksichtigung der Groß- und Kleinschreibung:

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

Oder verwenden Sie eine StringErweiterung ohne Berücksichtigung der Groß- und Kleinschreibung :

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
Sie müssen import Foundation, sonst wird dies nicht funktionieren.
Andrii Chernenko

Entweder import UIKitdie import Foundationerforderlich ist , zumindest mit iOS 11 und Swift 4.
Murray Sagal

Aber das unterscheidet zwischen Groß- und Kleinschreibung. Wie macht man einen Vergleich, während man den Fall ignoriert? Wie in Java String.equalsIgnoreCase (anotherString)?
Zulkarnain Shah

@zulkarnainshah Ich habe der Antwort ein Beispiel hinzugefügt.
Murray Sagal

@ MurraySagal Das ist immer noch keine Suche ohne Berücksichtigung der Groß- und Kleinschreibung. Sie konvertieren die ursprüngliche Zeichenfolge in Kleinbuchstaben und vergleichen diese dann explizit mit einer Zeichenfolge in Kleinbuchstaben. Es wird den Job machen, aber das ist nicht der ideale Weg, das zu tun
Zulkarnain Shah

22

In Swift 4.2

Verwenden

func contains(_ str: String) -> Bool

Beispiel

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

4
Bitte beachten Sie, dass Sie hierfür Foundation importieren müssen.
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")
}

Ausgabe

String Contains Another String

15

Sie können dies in Swift sehr einfach mit dem folgenden Code tun:

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

10

Nur ein Nachtrag zu den Antworten hier.

Sie können auch einen lokalen Test ohne Berücksichtigung der Groß- und Kleinschreibung durchführen, indem Sie Folgendes verwenden:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

Beispiel:

    import Foundation

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

AKTUALISIEREN

Dies ist Teil des Foundation Frameworks für iOS und Mac OS X 10.10.x und war zum Zeitpunkt meiner ursprünglichen Veröffentlichung Teil von 10.10.

Dokument generiert: 2014-06-05 12:26:27 -0700 OS X Versionshinweise Copyright © 2014 Apple Inc. Alle Rechte vorbehalten.

Versionshinweise zu OS X 10.10 Cocoa Foundation Framework

NSString bietet jetzt die folgenden zwei praktischen Methoden:

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

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


1
Beachten Sie, dass für diesen Ansatz iOS 8 erforderlich ist.
Andrew Ebling

9

Hier ist mein erster Versuch auf dem schnellen Spielplatz. Ich erweitere String durch die Bereitstellung von zwei neuen Funktionen (enthält und enthältIgnoreCase)

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

Verwenden Sie es so

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

Ich würde mich über Feedback freuen :)


Nächster Schritt: Machen Sie dies zu einer generischen Funktion, die auf allen Sammlungen funktioniert :-) Überprüfen Sie beispielsweise die eingebaute Funktion opensWith (). In der Variante 'Groß- / Kleinschreibung ignorieren' werden die Zeichenfolgen nur einmal in Kleinbuchstaben geschrieben (lassen Sie lc = other.lowercaseString vor dem Do)
hnh

9

Von allen Antworten hier denke ich, dass sie entweder nicht funktionieren oder ein bisschen hacken (zurück zu NSString). Es ist sehr wahrscheinlich, dass sich die richtige Antwort darauf mit den verschiedenen Beta-Versionen geändert hat.

Folgendes benutze ich:

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

Das "! = Null" wurde mit Beta 5 benötigt.


6

Hier sind Sie ja:

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

Manchmal benötigen Sie möglicherweise ein kompaktes Formular wie folgt: let rangeIfExists = string.rangeOfString ("Swift") ?? false, das entweder false als Booleschen Wert zurückgibt, wenn es nicht enthalten ist, oder den NSRange anderweitig
Stéphane de Luca

5

Sie müssen hierfür keinen benutzerdefinierten Code schreiben. Ab der Version 1.2 verfügt Swift bereits über alle Methoden, die Sie benötigen:

  • Stringlänge abrufen : count(string);
  • Überprüfen, ob der String einen Teilstring enthält : contains(string, substring);
  • Überprüfen, ob der String mit dem Teilstring beginnt: startsWith(string, substring)
  • und ETC.

Swift 2 ist nicht dasselbe.
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

Bitte schön! Bereit für Xcode 8 und 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 ist nur in 10.10 Yosemite (und wahrscheinlich iOS8) verfügbar. Auch die Überbrückung mit ObjectiveC stürzt in 10.9 ab. Sie versuchen, einen NSString an NSCFString zu übergeben. Ich kenne den Unterschied nicht, aber ich kann 10.9 barfs sagen, wenn dieser Code in einer OS X 10.9-App ausgeführt wird.

Hier sind die Unterschiede in Swift mit 10.9 und 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/index.html enthältString ist nur in 10.10 verfügbar

Der obige String-Bereich funktioniert unter 10.9 hervorragend. Ich finde, dass die Entwicklung auf 10.9 mit Xcode Beta2 super stabil ist. Ich benutze keine Spielplätze durch oder die Kommandozeilenversion von Spielplätzen. Ich finde, wenn die richtigen Frameworks importiert werden, ist die automatische Vervollständigung sehr hilfreich.


3

Mit und neuer Syntax in Swift 4 können Sie einfach

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

Zeichenfolge ist Ihre Zeichenfolgenvariable


2

Xcode 8 / Swift 3 Version:

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

Sie können auch verwenden contains:

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

2

Überprüfen Sie, ob es "Hallo" enthält.

let s = "Hello World"

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

2

Schnelle 4- Wege-Suche nach Teilzeichenfolgen, einschließlich des erforderlichen Foundation(oder UIKit) Framework-Imports:

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

Wenn kein Foundation(oder UIKit) Framework importiert wird, str.contains("Can")wird ein Compilerfehler ausgegeben.


Diese Antwort spuckt die Antwort von manojlds wieder aus , was völlig richtig ist. Ich habe keine Ahnung , warum so viele Antworten so viel Mühe neu durchlaufen Foundation‚s - String.contains(subString: String)Methode.


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 und höher können Sie diese beiden NSStringMethoden verwenden:

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

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

Was? es sieht aus wie es nicht verfügbar ist? in der Version, die mit xcode 6.1
Ali

0

Ich habe einige interessante Anwendungsfälle gefunden. Diese Varianten verwenden die rangeOfString-Methode, und ich füge das Gleichheitsbeispiel hinzu, um zu zeigen, wie die Such- und Vergleichsfunktionen von Strings in Swift 2.0 am besten verwendet werden können

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

Später, nachdem ich Änderungen an self.myObject vorgenommen habe, kann ich auf die folgenden Zeichenfolgenvergleichsroutinen verweisen (Setup als Lazy-Variablen, die einen Bool zurückgeben). Dadurch kann man den Zustand jederzeit überprüfen.

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

Eine Variante davon tritt auf, wenn ich manchmal eine fehlende Eigenschaft für dieses Objekt analysieren muss. Bei einer Zeichenfolgensuche kann ich einen bestimmten Teilstring finden, der auf Null gesetzt ist (die Standardeinstellung beim Erstellen eines Objekts).

    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

Wenn Sie überprüfen möchten, ob ein String einen anderen Sub-String enthält oder nicht, können Sie dies auch so überprüfen:

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

Wenn Sie in dieser speziellen Zeichenfolge wissen möchten, ob sie den Fruchtnamen "Apfel" enthält oder nicht, können Sie Folgendes tun:

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

Hoffe das funktioniert bei dir.


-2

Sie können einfach das tun, was Sie erwähnt haben:

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

Aus den Dokumenten:

Swifts StringTyp ist nahtlos mit der NSString Klasse der Foundation verbunden . Wenn Sie mit dem Foundation-Framework in Cocoa oder Cocoa Touch arbeiten, NSStringsteht Stringzusätzlich zu den in diesem Kapitel beschriebenen String-Funktionen die gesamte API zur Verfügung, um jeden von Ihnen erstellten Wert aufzurufen . Sie können einen String-Wert auch für jede API verwenden, für die eine NSString-Instanz erforderlich ist.

Sie müssen import Foundationdie NSStringMethoden überbrücken und sie der String-Klasse von Swift zur Verfügung stellen.


Nicht ich, aber nein, das tut es nicht.
Cezar

ja. Versucht in einem Spielplatz, in einer Mac App und in einer iOS App. Auch auf dem Spielplatz versucht, Kakao, UIKit, Foundation und alle möglichen Kombinationen der drei zu importieren (außer Kakao / UIKit, was keinen Sinn macht)
Cezar

Dies ist ab Swift 1.2
Kelvin Lau

-4

SWIFT 4 ist sehr einfach !!

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

1
Wie unterscheidet sich das von einigen der anderen Antworten hier?
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") ^~~~~ Durch die Bereitstellung einer nicht getesteten Antwort, die nicht funktioniert. Drucken! = Drucken.
Fred Gannett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.