SwiftのstartsWithメソッド?


151

Swiftには、startsWith()メソッドなどのようなものはありますか?

基本的に、特定の文字列が別の文字列で始まるかどうかを確認しようとしています。また、大文字と小文字を区別しないでください。

ご存知かもしれませんが、私は単純な検索機能を実行しようとしているだけですが、これで無残に失敗しているようです。

これは私が欲しいものです:

「sa」と入力すると、「San Antonio」、「Santa Fe」などの結果が表示されます。「SA」、「Sa」、または「sA」と入力すると、「San Antonio」または「Santa Fe」も返されます。

使っていた

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

iOS9以前は問題なく動作していました。ただし、iOS9にアップグレードすると機能しなくなり、検索で大文字と小文字が区別されるようになりました。

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

CaseInsensitiveSearchを使用したrangeOfStringが期待どおりに機能しない具体的な例を挙げていただけますか?私はそれをiOS 9 Simulatorでテストしましたが、うまくいきました。
マーティンR

回答:


362

hasPrefix代わりに使用しますstartsWith

例:

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

2
OPは大文字と小文字を区別しないように求め、あなたの答えは大文字と小文字を区別
C –ur

13
比較する前に文字列を小文字にするのはとても簡単です"string".lowercased()
TotoroTotoro

12

ここにstartsWithのSwift拡張実装があります:

extension String {

  func startsWith(string: String) -> Bool {

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

    return range.startIndex == startIndex
  }

}

使用例:

var str = "Hello, playground"

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

10

特に大文字と小文字を区別しないプレフィックスマッチングに回答するには:

純粋なSwift(ほとんどの場合推奨)

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

または:

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

注:空の接頭辞の場合""、両方の実装が返されますtrue

財団を使用して range(of:options:)

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

注:空の接頭辞の""場合は次を返しますfalse

正規表現で醜い(私はそれを見た...)

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

注:空の接頭辞の""場合は次を返しますfalse


6

迅速に4 func starts<PossiblePrefix>(with possiblePrefix: PossiblePrefix) -> Bool where PossiblePrefix : Sequence, String.Element == PossiblePrefix.Elementが導入されます。

使用例:

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

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

6

編集:Swift 3用に更新されました。

Swift Stringクラスには大文字と小文字を区別するメソッドhasPrefix()がありますが、大文字と小文字を区別しない検索が必要な場合は、NSStringメソッドを使用できますrange(of:options:)

注:デフォルトでは、NSStringメソッドは使用できませんが、import Foundation

そう:

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

オプションは、.caseInsensitiveまたはとして指定できます[.caseInsensitive]。次のような追加オプションを使用する場合は、2番目を使用します。

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

このアプローチには、検索など、検索で他のオプションを使用できるという利点もあり.diacriticInsensitiveます。同じ結果は、単に. lowercased()文字列を使用するだけでは達成できません。


1

Swift 3バージョン:

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

で高速化できます.anchored。私の答えまたはオリバー・アトキンソンの答えを見てください。
・クール

1

拡張機能付きのSwift 4

私の拡張機能の例には3つの関数が含まれています。サブストリングで文字列の開始を確認し、サブストリングで文字列の終了を確認し、文字列サブストリングが含まれていることを確認します。

isCaseSensitive-parameterをfalseに設定します。無視したい場合は、文字「A」または「a」です。それ以外の場合は、trueに設定します。

機能の詳細については、コード内のコメントを参照してください。

コード:

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

使用例:

チェックするには、文字列を「TEST」で開始します。

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

確認するには、文字列を「test」で開始します。

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

チェックするには、文字列を「G123」で終了します。

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

チェックするには、文字列を「g123」で終了します。

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

チェックのために、文字列には「RING12」が含まれています。

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

確認のために、文字列には「ring12」が含まれています。

    "testString123".containsSubString(theSubString: "ring12", isCaseSensitive: true) // Returns true
    "testString123".containsSubString(theSubString: "ring12", isCaseSensitive: false) // Returns true
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.