Swift Regex (WWDC 2022) - ehrldyd15/Swift_Skills GitHub Wiki
Swift Regex API๋ IOS 16๋ถํฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
init(String) throws๋ฅผ ์ฌ์ฉ
let regex = try Regex(#"Hi, WWDC\d{2}!"#)
#"..."# ํจํด์ ์ฌ์ฉํ๋ฉด string์ escaping์ ๋ฐ๋ก ์์ฑํ์ง ์์๋ ๋๋ค.
// ๋ด์ ์ ๊ทํํ์์ ์ฌ์ฉํ๋ฉด ์ปดํ์ผ๋ฌ๊ฐ Regex ํ์
์ผ๋ก ๋ฐ๊ฟ์ค๋ค.
let regex = /Hi, WWDC\d{2}!/
/.../ ํจํด์ Regex Literal ์ด๋ผ ๋ถ๋ฅธ๋ค.
@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
extension Regex {
public init<Content>(@RegexComponentBuilder _ content: () -> Content) where Output == Content.RegexOutput, Content : RegexComponent
}
RegexBuilder ๋ชจ๋ ๋ด์๋ ์์ ๊ฐ์ extension์ด ์๋ค.
(์ฐธ๊ณ : https://developer.apple.com/documentation/RegexBuilder)
๋ฐ๋ผ์ RegexBuilder๋ฅผ importํ๋ฉด RegexBuilder๋ฅผ ์ด์ฉํ์ฌ DSL ๋ฐฉ์์ผ๋ก ์ ๊ทํํ์์ ์์ฑํ ์ ์๋ค.
import RegexBuilder
let regex = Regex {
"Hi, WWDC"
Repeat(.digit, count: 2)
"!"
}
๋ฌธ๋ฒ์ ์ ๋ชฐ๋ผ๋ ์ฝ๋๋ก ๋ฐ๋ก ์์ฑ์ด ๊ฐ๋ฅํ๋ค.
๋ณต์กํ ํํ์์ ์ํ์ฌ ๋ณต์กํ ์ฝ๋๋ฅผ ์์ฑํ ํ์๋ ์์ด

body์ Regex literal์ ๋ฐ๋ก ํฌํจ์ํฌ ์ ์๋ค.

์ ์ฒ๋ผ ์น์ํ regex literal์ ํฌํจํ๋ ์์ผ๋ก ์จ๋ ๋๋ค.


๊ทธ์กฐ๊ฐ ์ ์ฒ๋ผ ๋์ด ์์ด์
Regex์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด๋ ๋๊ณ Foundation์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ค์ ์ฌ์ฉํด๋ ๋๋ค.
์๋ฅผ๋ค์ด, ์ฒซ๋ฒ์งธ๋ก ๋งค์นญ๋๋ ๊ฒ์ ์ฐพ๊ณ ์ถ์ ๋
Regex์ ๋ฉ์๋์ธ firstMatch(in:)์ ์ฌ์ฉํ๊ฑฐ๋
BidirectionalCollection (Int, String, Array ๋ฑ์ด ์ปจํํ๋ ํ๋กํ ์ฝ)์ ์๋ firstMatch(of:)๋ฅผ ์ฌ์ฉํด๋ ๋๋ค.
import RegexBuilder
let regex = Regex {
"Hi, WWDC"
Repeat(.digit, count: 2)
"!"
}
let input = "Hi, WWDC21! Hi, WWDC22! Hi Hello"
let match1 = try regex.firstMatch(in: input)?.output // Hi, WWDC21!
let match2 = input.firstMatch(of: regex)?.output // Hi, WWDC21!
์ฐธ๊ณ ๋ก Regex์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ค์ string๋ง ๋ฐ์ ์ ์๊ณ ,
WWDC์์๋ Foundation ๋ฉ์๋๋ค์ ๊ธฐ๋ฐ์ผ๋ก ์ค๋ช ํ๋ค.
firstMatch: ์ฒซ๋ฒ์งธ๋ก regex์ ๋งค์นญ๋๋ ๋ฌธ์์ด ๋ฆฌํด
wholeMatch: ์ ์ฒด ๋ฌธ์ฅ์ด ๋ชจ๋ regex์ ๋งค์นญ๋๋ ๋ฌธ์์ด ๋ฆฌํด
matches: ๋งค์นญ๋๋ ๋ชจ๋ ๋ฌธ์์ด collection ๋ฆฌํด
import RegexBuilder
let regex = Regex {
"Hi, WWDC"
Repeat(.digit, count: 2)
"!"
}
let input = "Hi, WWDC21! Hi, WWDC22! Hi Hello"
let firstMatch: Regex.Match? = input.firstMatch(of: regex)
print("First Matched: \(firstMatch?.output)")
// First Matched: Optional("Hi, WWDC21!")
let wholeMatch: Regex.Match? = input.wholeMatch(of: regex)
print("Whole Matched: \(wholeMatch?.output)")
// Whole Matched: nil
let matches: [Regex.Match] = input.matches(of: regex)
print("Matched: \(matches.map { $0.output })")
// Matched: ["Hi, WWDC21!", "Hi, WWDC22!"]
๋ฆฌํด ํ์ ์ธ Regex.Match์ ๋งค์นญ ๊ฒฐ๊ณผ๋ฅผ ๋ด๊ณ ์์ผ๋ฉฐ output๊ณผ range๋ฅผ ์ ๊ณตํ๋ค.
RegexBuilder์ Capture๋ฅผ ์ฌ์ฉํ๋ฉด ์ํ๋ ๋ฌธ์์ด์ ์บก์ณํ ์ ์๋ค.
import RegexBuilder
let regex = Regex {
"Hi, WWDC"
Capture {
Repeat(.digit, count: 2)
}
"!"
}
let input = "Hi, WWDC21! Hi, WWDC22! Hi Hello"
if let firstMatch = input.firstMatch(of: regex) {
let (firstMatched, digits) = firstMatch.output
print(firstMatched) // Hi, WWDC21!
print(digits) // 21
}