見出し画像

New Swift! 2022 - closure,time,regex

closure

クロージャーの返り値の型推論が少し強くなったようです。

これからは

let scores = [100, 80, 85]

let results = scores.map { score in
    if score >= 85 {
        return "\(score)%: Pass"
    } else {
        return "\(score)%: Fail"
    }
}

print(results)

今までは

let oldResults = scores.map { score -> String in
    if score >= 85 {
        return "\(score)%: Pass"
    } else {
        return "\(score)%: Fail"
    }
}

score -> String

返り値の型名をつけなくて良くなりまいした。


time

時間や期間を表すオブジェクトが追加されましたようです。使い方がもう一つわかりません。


Regular expressions 正規表現

let message = "the cat sat on the mat"

print(message.ranges(of: "at"))
print(message.replacing("cat", with: "dog"))
print(message.trimmingPrefix("the "))

文字列を操作するようなコードがあります。これは以下のように正規表現でも置き換えることができます。

print(message.ranges(of: /[a-z]at/))
print(message.replacing(/[a-m]at/, with: "dog"))
print(message.trimmingPrefix(/The/.ignoresCase()))

[a-z]at

これはアルファベット(a,b,c ・・・z ) + atの組み合わせを全ての範囲"ranges"を見つけます。cat,sat,matの範囲が出力されます。

[a-m]at

これはアルファベット(a,b,c ・・・m) + at の組み合わせを"dog"で入れ替え"replacing"します。cat,matが該当して入れ替えられます。


/The/.ignoresCase())

これは"The"を見つけて取り除きます。

少し違う書き方もできます。

do {
    let atSearch = try Regex("[a-m]at")
    print(message.replacing(atSearch, with: "dog"))
} catch {
    print("Failed to create regex")
}

これで"sat","mat"と"dog"を入れ替えます。

文章の中に探したい文字列 (.+?)、 (\d+)を抜き出す方法として、

let search1 = /My name is (.+?) and I'm (\d+) years old./
let greeting1 = "My name is Taylor and I'm 26 years old."

if let result = try search1.wholeMatch(in: greeting1) {
    print("Name: \(result.1)")
    print("Age: \(result.2)")
}

(result.1)

文字列の取り出しはその1,2というような順番で指定してやります。

let search2 = /My name is (?<name>.+?) and I'm (?<age>\d+) years old./
let greeting2 = "My name is Taylor and I'm 26 years old."

if let result = try search2.wholeMatch(in: greeting2) {
    print("Name: \(result.name)")
    print("Age: \(result.age)")
}

(?<name>.+?)

これは名前をつけて取り出す方法です。

\(result.name)

として取り出すことができます。


もう一つ取り出す方法として

DSLでより可読性高く正規表現を組み立てられるようになりました。

import RegexBuilder

let greeting = "My name is Taylor and I'm 26 years old."

let nameRef = Reference(Substring.self)
let ageRef = Reference(Int.self)

let search5 = Regex {
    "My name is "

    Capture(as: nameRef) {
        OneOrMore(.word)
    }

    " and I'm "

    TryCapture(as: ageRef) {
        OneOrMore(.digit)
    } transform: { match in
        Int(match)
    }

    Capture(.digit)

    " years old."
}

if let result = greeting.firstMatch(of: search5) {
    print("Name: \(result[nameRef])")
    print("Age: \(result[ageRef])")
}

import RegexBuilder

が必要です。


この記事が気に入ったらサポートをしてみませんか?