Swift bắt đầu với phương pháp nào?


151

Có thứ gì như phương thức startedWith () hoặc thứ gì đó tương tự trong Swift không?

Về cơ bản, tôi đang cố kiểm tra xem một chuỗi nào đó có bắt đầu bằng một chuỗi khác không. Tôi cũng muốn nó không nhạy cảm.

Như bạn có thể nói, tôi chỉ đang cố gắng thực hiện một tính năng tìm kiếm đơn giản nhưng dường như tôi đang thất bại thảm hại về việc này.

Đây là những gì tôi muốn:

gõ "sa" sẽ cho tôi kết quả cho "San Antonio", "Santa Fe", v.v. gõ "SA" hoặc "Sa" hoặc thậm chí "sA" cũng sẽ trả về "San Antonio" hoặc "Santa Fe".

tôi đang sử dụng

self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil 

trước iOS9 và nó đã hoạt động tốt. Tuy nhiên, sau khi nâng cấp lên iOS9, nó đã ngừng hoạt động và bây giờ các tìm kiếm có phân biệt chữ hoa chữ thường.

    var city = "San Antonio"
    var searchString = "san "
    if(city.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil){
        print("San Antonio starts with san ");
    }

    var myString = "Just a string with san within it"

    if(myString.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil){
        print("I don't want this string to print bc myString does not start with san ");
    }

Bạn có thể đưa ra một ví dụ cụ thể trong đó RangeOfString với CaseInsensitiveSearch không hoạt động như mong đợi không? Tôi đã thử nghiệm nó trong Trình mô phỏng iOS 9 và nó hoạt động với tôi.
Martin R

Câu trả lời:


362

sử dụng hasPrefixthay vì startsWith.

Thí dụ:

"hello dolly".hasPrefix("hello")  // This will return true
"hello dolly".hasPrefix("abc")    // This will return false

2
OP hỏi đối với trường hợp không nhạy cảm và câu trả lời của bạn là trường hợp nhạy cảm
Cœur

13
Thật dễ dàng để tạo các chuỗi chữ thường trước khi so sánh bằng cách sử dụng"string".lowercased()
TotoroTotoro

12

đây là một triển khai mở rộng Swift của startedWith:

extension String {

  func startsWith(string: String) -> Bool {

    guard let range = rangeOfString(string, options:[.AnchoredSearch, .CaseInsensitiveSearch]) else {
      return false
    }

    return range.startIndex == startIndex
  }

}

Ví dụ sử dụng:

var str = "Hello, playground"

let matches    = str.startsWith("hello") //true
let no_matches = str.startsWith("playground") //false

10

Để trả lời cụ thể trường hợp khớp tiền tố không nhạy cảm :

trong Swift thuần túy (được khuyên dùng hầu hết thời gian)

extension String {
    func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
        return lowercased().hasPrefix(prefix.lowercased())
    }
}

hoặc là:

extension String {
    func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
        return lowercased().starts(with: prefix.lowercased())
    }
}

lưu ý: đối với tiền tố trống, ""cả hai triển khai sẽ trả vềtrue

sử dụng Foundation range(of:options:)

extension String {
    func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
        return range(of: prefix, options: [.anchored, .caseInsensitive]) != nil
    }
}

lưu ý: đối với tiền tố trống, ""nó sẽ trả vềfalse

và trở nên xấu xí với một regex (Tôi đã nhìn thấy nó ...)

extension String {
    func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
        guard let expression = try? NSRegularExpression(pattern: "\(prefix)", options: [.caseInsensitive, .ignoreMetacharacters]) else {
            return false
        }
        return expression.firstMatch(in: self, options: .anchored, range: NSRange(location: 0, length: characters.count)) != nil
    }
}

lưu ý: đối với tiền tố trống, ""nó sẽ trả vềfalse


6

Trong swift 4 func starts<PossiblePrefix>(with possiblePrefix: PossiblePrefix) -> Bool where PossiblePrefix : Sequence, String.Element == PossiblePrefix.Elementsẽ được giới thiệu.

Ví dụ sử dụng:

let a = 1...3
let b = 1...10

print(b.starts(with: a))
// Prints "true"

6

Chỉnh sửa: cập nhật cho Swift 3.

Lớp Swift String không có phương thức hasPrefix()phân biệt chữ hoa chữ thường, nhưng nếu bạn muốn tìm kiếm không phân biệt chữ hoa chữ thường, bạn có thể sử dụng phương thức NSString range(of:options:).

Lưu ý: Theo mặc định, các phương thức NSString không có sẵn, nhưng nếu bạn import Foundationcó.

Vì thế:

import Foundation
var city = "San Antonio"
var searchString = "san "
let range = city.range(of: searchString, options:.caseInsensitive)
if let range = range {
    print("San Antonio starts with san at \(range.startIndex)");
}

Các tùy chọn có thể được cho là một trong hai .caseInsensitivehoặc [.caseInsensitive]. Bạn sẽ sử dụng cái thứ hai nếu bạn muốn sử dụng các tùy chọn bổ sung, chẳng hạn như:

let range = city.range(of: searchString, options:[.caseInsensitive, .backwards])

Cách tiếp cận này cũng có lợi thế là có thể sử dụng các tùy chọn khác với tìm kiếm, chẳng hạn như .diacriticInsensitivetìm kiếm. Kết quả tương tự không thể đạt được chỉ bằng cách sử dụng . lowercased()trên các chuỗi.


1

Phiên bản Swift 3:

func startsWith(string: String) -> Bool {
    guard let range = range(of: string, options:[.caseInsensitive]) else {
        return false
    }
    return range.lowerBound == startIndex
}

có thể nhanh hơn với .anchored. Xem câu trả lời của tôi hoặc câu trả lời của Oliver Atkinson.
Cœur

1

Trong Swift 4 có phần mở rộng

Ví dụ tiện ích mở rộng của tôi chứa 3 hàm: kiểm tra thực hiện Chuỗi bắt đầu với một SubString, thực hiện kết thúc Chuỗi thành một SubString và thực hiện Chuỗi có chứa một SubString.

Đặt tham số isCaseSensitive thành false, nếu bạn muốn bỏ qua là các ký tự "A" hoặc "a", nếu không thì đặt nó thành true.

Xem các ý kiến ​​trong mã để biết thêm thông tin về cách thức hoạt động.

Mã số:

    import Foundation

    extension String {
        // Returns true if the String starts with a substring matching to the prefix-parameter.
        // If isCaseSensitive-parameter is true, the function returns false,
        // if you search "sA" from "San Antonio", but if the isCaseSensitive-parameter is false,
        // the function returns true, if you search "sA" from "San Antonio"

        func hasPrefixCheck(prefix: String, isCaseSensitive: Bool) -> Bool {

            if isCaseSensitive == true {
                return self.hasPrefix(prefix)
            } else {
                var thePrefix: String = prefix, theString: String = self

                while thePrefix.count != 0 {
                    if theString.count == 0 { return false }
                    if theString.lowercased().first != thePrefix.lowercased().first { return false }
                    theString = String(theString.dropFirst())
                    thePrefix = String(thePrefix.dropFirst())
                }; return true
            }
        }
        // Returns true if the String ends with a substring matching to the prefix-parameter.
        // If isCaseSensitive-parameter is true, the function returns false,
        // if you search "Nio" from "San Antonio", but if the isCaseSensitive-parameter is false,
        // the function returns true, if you search "Nio" from "San Antonio"
        func hasSuffixCheck(suffix: String, isCaseSensitive: Bool) -> Bool {

            if isCaseSensitive == true {
                return self.hasSuffix(suffix)
            } else {
                var theSuffix: String = suffix, theString: String = self

                while theSuffix.count != 0 {
                    if theString.count == 0 { return false }
                    if theString.lowercased().last != theSuffix.lowercased().last { return false }
                    theString = String(theString.dropLast())
                    theSuffix = String(theSuffix.dropLast())
                }; return true
            }
        }
        // Returns true if the String contains a substring matching to the prefix-parameter.
        // If isCaseSensitive-parameter is true, the function returns false,
        // if you search "aN" from "San Antonio", but if the isCaseSensitive-parameter is false,
        // the function returns true, if you search "aN" from "San Antonio"
        func containsSubString(theSubString: String, isCaseSensitive: Bool) -> Bool {

            if isCaseSensitive == true {
                return self.range(of: theSubString) != nil
            } else {
                return self.range(of: theSubString, options: .caseInsensitive) != nil
            }
        }
    }

Ví dụ về cách sử dụng:

Để kiểm tra, hãy bắt đầu Chuỗi với "TEST":

    "testString123".hasPrefixCheck(prefix: "TEST", isCaseSensitive: true) // Returns false
    "testString123".hasPrefixCheck(prefix: "TEST", isCaseSensitive: false) // Returns true

Để kiểm tra, hãy bắt đầu Chuỗi bằng "test":

    "testString123".hasPrefixCheck(prefix: "test", isCaseSensitive: true) // Returns true
    "testString123".hasPrefixCheck(prefix: "test", isCaseSensitive: false) // Returns true

Để kiểm tra, hãy kết thúc Chuỗi bằng "G123":

    "testString123".hasSuffixCheck(suffix: "G123", isCaseSensitive: true) // Returns false
    "testString123".hasSuffixCheck(suffix: "G123", isCaseSensitive: false) // Returns true

Để kiểm tra, hãy kết thúc Chuỗi bằng "g123":

    "testString123".hasSuffixCheck(suffix: "g123", isCaseSensitive: true) // Returns true
    "testString123".hasSuffixCheck(suffix: "g123", isCaseSensitive: false) // Returns true

Để kiểm tra, chuỗi có chứa "RING12":

    "testString123".containsSubString(theSubString: "RING12", isCaseSensitive: true) // Returns false
    "testString123".containsSubString(theSubString: "RING12", isCaseSensitive: false) // Returns true

Để kiểm tra, Chuỗi có chứa "ring12":

    "testString123".containsSubString(theSubString: "ring12", isCaseSensitive: true) // Returns true
    "testString123".containsSubString(theSubString: "ring12", isCaseSensitive: false) // Returns true
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.