Làm cách nào để kiểm tra xem một chuỗi có chứa chuỗi khác trong Swift không?


535

Trong Objective-Cmã để kiểm tra một chuỗi con trong một NSStringlà:

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

Nhưng làm thế nào để tôi làm điều này trong Swift?


2
@rckoenes Tôi mới đến swift, tôi biết cách thực hiện mục tiêu
nàyC

1
Vậy thì tại sao bạn không bắt đầu một sân chơi và thử nó.
RCkoenes

Nếu bạn vẫn ở đây, vui lòng thay đổi câu trả lời được chấp nhận thành câu trả lời của người dùng1021430 ... đúng rồi
Dan Rosenstark

Câu trả lời:


1044

Bạn có thể thực hiện chính xác cùng một cuộc gọi với Swift:

Swift 4 & Swift 5

Trong Swift 4 String là một tập hợp các Charactergiá trị, nó không giống như trong Swift 2 và 3, vì vậy bạn có thể sử dụng mã 1 ngắn gọn hơn này :

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 cũ hơn

var string = "hello Swift"

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

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

Tôi hy vọng đây là một giải pháp hữu ích vì một số người, bao gồm cả tôi, đã gặp phải một số vấn đề lạ bằng cách gọi containsString(). 1

Tái bút Đừng quênimport Foundation

Chú thích

  1. Chỉ cần nhớ rằng việc sử dụng các hàm bộ sưu tập trên Chuỗi có một số trường hợp cạnh có thể mang lại cho bạn kết quả không mong muốn, ví dụ như khi xử lý biểu tượng cảm xúc hoặc các cụm biểu đồ khác như các chữ cái có dấu.

13
Tài liệu của Apple nói: 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 (@"").Vì vậy, có lẽ chỉ cần kiểm tra nilsẽ không hoạt động đúng.
Alex

7
chuỗi.lowercaseString.rangeOfString ("swift"). location! = NSNotFound. Vui lòng đọc tài liệu .. bạn sẽ không nhận được một đối tượng không.
TheCodingArt

4
@TheGamingArt Có bạn sẽ làm được. Swift khứ hồi toàn bộ mọi thứ cho bạn một cách tự động để nếu NSRange là {NSNotFound, 0}nó được đại diện cho bạn là con số không. Nếu đó là một phạm vi thực tế, nó được đại diện cho bạn dưới dạng Phạm vi Swift (tùy chọn). Mát mẻ.
matt

4
Grr. chứaString không có trong tài liệu, kể cả Xcode 6.3.1.
Duncan C

19
@TheGoonie: Đây không phải là kêu gọi NSString's .rangeOfString(). Đây được gọi String.rangeOfString(), được khai báo làfunc rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
newacct

192

Cách mở rộng

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

Nói chung Swift 4 có chứa phương thức tuy nhiên nó có sẵn từ iOS 8.0 trở lên


Swift 3.1

Bạn có thể viết phần mở rộng contains:containsIgnoringCasechoString

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

Phiên bản Swift cũ hơn

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

Thí dụ:

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
để bỏ qua trường hợp sử dụng return self.rangeOfString (tìm, tùy chọn: NSStringCompareOptions.CaseInsensitiveSearch)! = nil
masgar

1
Không còn cần thiết trừ khi bạn không có Foundation... containsStringhoạt động tốt.
Dan Rosenstark

5
cho nhanh 3.0. Thay đổi thành bên dưới: chuỗi mở rộng {func chứa (find: String) -> Bool {return self.range (of: find)! = Nil} func chứaIgnoringCase (find: String) -> Bool {return self.range (of: find , tùy chọn: .caseInsensitive)! = nil}}
Michael Shang

Đối với Swift 4 -> Chuỗi mở rộng {func chứa (find: String) -> Bool {return self.range (of: find)! = Nil} func chứaIgnoringCase (find: String) -> Bool {return self.range (of: tìm, tùy chọn: .caseInsensitive)! = nil}}
shokaveli

50

Từ các tài liệu, có vẻ như việc gọi containsString()Chuỗi sẽ hoạt động:

Kiểu Chuỗi của Swift được kết nối liền mạch với lớp NSString của Foundation. Nếu bạn đang làm việc với khung Foundation trong Ca cao hoặc Ca cao cảm ứng, toàn bộ API NSString có sẵn để gọi bất kỳ giá trị Chuỗi nào bạn tạo, ngoài các tính năng Chuỗi được mô tả trong chương này. Bạn cũng có thể sử dụng giá trị Chuỗi với bất kỳ API nào yêu cầu phiên bản NSString.

Tuy nhiên, nó dường như không hoạt động theo cách đó.

Nếu bạn cố gắng sử dụng someString.containsString(anotherString), bạn sẽ nhận được một lỗi thời gian biên dịch 'String' does not contain a member named 'containsString'.

Vì vậy, bạn còn lại một vài lựa chọn, một trong số đó là kết nối rõ ràng Stringvới Objective-C bằng cách sử dụng bridgeToObjectiveC()hai tùy chọn khác liên quan đến việc sử dụng một cách rõ ràng NSStringvà lựa chọn cuối cùng liên quan đến việc truyền StringtớiNSString

Bằng cách bắc cầu, bạn sẽ nhận được:

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

Bằng cách gõ rõ ràng chuỗi là một NSString, bạn sẽ nhận được:

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

Nếu bạn đã có String, bạn có thể khởi tạo NSString từ nó bằng cách sử dụng NSString (chuỗi :):

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

Và cuối cùng, bạn có thể cast một hiện Stringmột NSStringnhư sau

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

4
Ví dụ cuối cùng (tôi chưa thử người khác) gặp sự cố với tôi trên iOS 7 (thiết bị); Các ứng dụng Swift chỉ chạy tốt trên iOS 7. Lỗi tôi gặp phải là [__NSCFString containsString:]: unrecognized selector sent to instance. Ngoài ra, tôi không thể tìm thấy phương thức containsStringtrong tài liệu dev để xác nhận xem nó có mới cho iOS 8.
Jason Leach

Hấp dẫn. Tôi chỉ thử nghiệm điều này trên một sân chơi. Tôi sẽ thử lại sau khi tôi sử dụng máy tính.
Cezar

các tùy chọn thứ ba và thứ tư là những cái duy nhất mà trình biên dịch cho phép. cả hai đều gặp sự cố với tôi trong phiên bản beta 4 trong iOS 7.
palmi

38

Một số khác. Hỗ trợ các tùy chọn trường hợp và dấu phụ.

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

Sử dụng

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

iOS 9+

Chức năng không nhạy cảm trường hợp và dấu phụ có sẵn kể từ iOS 9.

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

31

Kể từ Xcode 7.1 và Swift 2.1 containsString()đang hoạt động tốt đối với tôi.

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

Swift 4:

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

Và một ví dụ Swift 4 không nhạy cảm:

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

Hoặc sử dụng một Stringphần mở rộng không nhạy cảm trường hợp :

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
bạn cần import Foundation, nếu không điều này sẽ không hoạt động.
Andrii Chernenko

Hoặc là import UIKitcác import Foundationlà cần thiết, ít nhất là với iOS 11 và Swift 4.
Murray Sagal

Nhưng đó là trường hợp nhạy cảm. Làm thế nào để bạn làm so sánh trong khi bỏ qua trường hợp. Giống như trong java String.equalsIgnoreCase (AnotherString)?
zulkarnain shah

@zulkarnainshah Tôi đã thêm một ví dụ cho câu trả lời.
Murray Sagal

@M bồSagal Thats vẫn không tìm kiếm trường hợp không nhạy cảm. Bạn đang chuyển đổi chuỗi gốc thành chữ thường và sau đó so sánh rõ ràng với chuỗi chữ thường. Nó sẽ thực hiện công việc, nhưng đó không phải là cách lý tưởng để làm điều đó
zulkarnain shah 7/11/2017

22

Trong Swift 4.2

Sử dụng

func contains(_ str: String) -> Bool

Thí dụ

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

4
Xin lưu ý rằng điều này yêu cầu bạn nhập Foundation.
rmaddy

16

> TRÊN NỀN TẢNG 3.0

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

Đầu ra

String Contains Another String

15

Bạn có thể làm điều này rất dễ dàng trong Swift bằng cách sử dụng mã:

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

10

Chỉ là một phụ lục cho các câu trả lời ở đây.

Bạn cũng có thể thực hiện một thử nghiệm không nhạy cảm trường hợp địa phương bằng cách sử dụng:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

Thí dụ:

    import Foundation

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

CẬP NHẬT

Đây là một phần của Khung nền tảng cho iOS & Mac OS X 10.10.x và là một phần của 10.10 tại Thời điểm đăng bài gốc của tôi.

Tài liệu được tạo: 2014-06-05 12:26:27 -0700 Ghi chú phát hành OS X Bản quyền © 2014 Apple Inc. Mọi quyền được bảo lưu.

Ghi chú phát hành OS X 10.10 Khung nền tảng ca cao

NSString hiện có hai phương thức tiện lợi sau:

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

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


1
Hãy lưu ý cách tiếp cận này yêu cầu iOS 8.
Andrew Eble

9

Đây là cú đâm đầu tiên của tôi vào lúc này trong sân chơi nhanh. Tôi mở rộng String bằng cách cung cấp hai hàm mới (chứa và chứaIgnoreCase)

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

Sử dụng nó như thế này

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

Tôi hoan nghênh mọi phản hồi :)


Bước tiếp theo: Biến nó thành một hàm chung hoạt động trên tất cả các Bộ sưu tập :-) Ví dụ: kiểm tra hàm dựng sẵn startedWith (). Trong biến thể 'trường hợp bỏ qua', chỉ viết thường các chuỗi một lần (hãy để lc = other.lowercaseString trước khi làm)
hnh

9

Trong tất cả các câu trả lời ở đây, tôi nghĩ rằng chúng không hoạt động, hoặc chúng là một chút hack (chuyển trở lại NSString). Rất có khả năng câu trả lời chính xác cho điều này đã thay đổi với các phiên bản beta khác nhau.

Đây là những gì tôi sử dụng:

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

"! = Nil" trở nên bắt buộc với Beta 5.


6

Của bạn đây:

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

Đôi khi bạn có thể cần một hình thức nhỏ gọn như sau: let Range IfExists = string.rangeOfString ("Swift") ?? false sẽ trả về false là boolean nếu nó không được chứa hoặc NSRange nếu không
Stéphane de Luca

5

Bạn không cần phải viết bất kỳ mã tùy chỉnh nào cho việc này. Bắt đầu từ phiên bản 1.2 Swift đã có tất cả các phương thức bạn cần:

  • độ dài chuỗi: count(string) ;
  • kiểm tra xem chuỗi có chứa chuỗi con không: contains(string, substring) ;
  • kiểm tra xem chuỗi có bắt đầu bằng chuỗi con không: startsWith(string, substring)
  • và vân vân.

Swift 2 không giống nhau.
Suragch

2
Swift 2 : string.hasPrefix (Khởi đầu))
SwiftArchitect

5

Trong Swift 3

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

4

Bạn đi đây! Sẵn sàng cho Xcode 8 và 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 chỉ khả dụng trong 10.10 Yosemite (và có thể là iOS8). Đồng thời bắc cầu cho ObjectiveC gặp sự cố trong 10.9. Bạn đang cố gắng chuyển NSString sang NSCFString. Tôi không biết sự khác biệt, nhưng tôi có thể nói 10,9 barfs khi nó thực thi mã này trong ứng dụng OS X 10.9.

Dưới đây là những điểm khác biệt trong Swift với 10.9 và 10.10: https://developer.apple.com/l Library / preselease / mac / documentation / General / Reference /APIDiffsMacOSX10_10SeedDiff / index.html chứaString chỉ có sẵn trong 10.10

Phạm vi chuỗi trên hoạt động tuyệt vời vào ngày 10.9. Tôi đang tìm cách phát triển vào ngày 10.9 là siêu ổn định với Xcode beta2. Tôi không sử dụng sân chơi thông qua hoặc phiên bản dòng lệnh của sân chơi. Tôi đang tìm kiếm nếu các khung thích hợp được nhập thì tự động hoàn thành là rất hữu ích.


3

Với và cú pháp mới trong swift 4, bạn có thể chỉ cần

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

chuỗi là biến chuỗi của bạn


2

Phiên bản 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")
}

Bạn cũng có thể sử dụng contains:

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

2

Kiểm tra xem nó có chứa 'Xin chào' không

let s = "Hello World"

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

2

Swift 4 cách để kiểm tra các chuỗi con, bao gồm nhập khung Foundation(hoặc UIKit) cần thiết :

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

Trừ khi Foundation(hoặc UIKit) khung được nhập, str.contains("Can")sẽ đưa ra lỗi trình biên dịch.


Câu trả lời này đang hồi sinh câu trả lời của manojlds , điều này hoàn toàn chính xác. Tôi không có ý tưởng tại sao rất nhiều câu trả lời đi qua rất nhiều khó khăn để tái Foundation's String.contains(subString: String)phương pháp.


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

Trong iOS 8 trở lên, bạn có thể sử dụng hai NSStringphương pháp sau:

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

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

Gì? có vẻ như nó không có sẵn? trong phiên bản đi kèm với xcode 6.1
Ali

0

Tôi đã tìm thấy một vài trường hợp sử dụng thú vị. Các biến thể này sử dụng phương thức RangeOfString và tôi bao gồm ví dụ về đẳng thức để cho thấy cách người ta có thể sử dụng tốt nhất các tính năng tìm kiếm và so sánh của Chuỗi trong Swift 2.0

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

Sau này sau khi tôi thực hiện các thay đổi cho self.myObject, tôi có thể tham khảo các thói quen so sánh chuỗi sau (thiết lập dưới dạng các biến lười biếng trả về Bool). Điều này cho phép một người kiểm tra trạng thái bất cứ lúc nào.

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

Một biến thể của điều này xảy ra khi đôi khi tôi cần phân tích một thuộc tính bị thiếu trên đối tượng đó. Một tìm kiếm chuỗi cho phép tôi tìm một chuỗi con cụ thể được đặt thành nil (mặc định khi một đối tượng được tạo).

    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

Nếu bạn muốn kiểm tra xem một Chuỗi có chứa một Chuỗi con khác trong đó hay không, bạn cũng có thể kiểm tra nó như thế này,

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

Bây giờ, trong chuỗi cụ thể này nếu bạn muốn biết liệu nó có chứa tên trái cây 'táo' hay không bạn có thể làm,

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

Hy vọng điều này làm việc cho bạn.


-2

Bạn chỉ có thể làm những gì bạn đã đề cập:

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

Từ các tài liệu:

StringKiểu của Swift được kết nối liền mạch với NSString lớp Foundation . Nếu bạn đang làm việc với khung Foundation trong Ca cao hoặc Ca cao cảm ứng, toàn bộ NSStringAPI có sẵn để gọi bất kỳ Stringgiá trị nào bạn tạo, ngoài các tính năng Chuỗi được mô tả trong chương này. Bạn cũng có thể sử dụng giá trị Chuỗi với bất kỳ API nào yêu cầu phiên bản NSString.

Bạn cần kết import Foundationnối các NSStringphương thức và cung cấp chúng cho lớp String của Swift.


Không phải tôi, nhưng không, nó không.
Cezar

Vâng. Đã thử trong Sân chơi, trong Ứng dụng Mac và trong ứng dụng iOS. Cũng đã thử trong Playground nhập ca cao, UIKit, Foundation và tất cả các kết hợp có thể có của ba người trong số họ (ngoại trừ ca cao / UIKit, không có ý nghĩa gì)
Cezar

Đây không còn là trường hợp của Swift 1.2
Kelvin Lau

-4

SWift 4 rất dễ dàng !!

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

1
Làm thế nào điều này khác với một số câu trả lời khác ở đây?
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") ^~~~~ Bằng cách cung cấp một câu trả lời chưa được kiểm tra mà không hoạt động. In! = In.
Fred Gannett
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.