목차
- 정규표현식이란?
- 정규식 문법
- swift에서 정규표현식을 사용하는 방법
- matching되는 부분 찾기
정규표현식이란?
정규식은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다.
이것만 봐선 잘 이해가 안가는데,
문자열을 메소드로 파싱해도 되지만, 문자열이 길어지거나 복잡해지고 가변적이라면 파싱하기 매우 까다롭잖아요?
문자열에서 특정 패턴에 부합하는 부분만 찾고 싶을 때 사용하는 게 바로 정규식입니다.
정규식 문법
문법에 대해선 많은 블로그에서 다루고 있으니 자주 사용하는 것들만 정리해보겠습니다.
Charcter | 의미 |
---|---|
| |
또는 |
() |
그룹 |
[] |
문자셋, 괄호안의 어떤 문자든 |
[^] |
첫 문자로 ^를 쓰면 괄호 내용의 부정. 즉 괄호 안에 포함되지 않는 한 문자 |
Charcter | 의미 |
---|---|
? |
없거나 있거나 (zero or one) |
* |
0개 이상 (zero or more) |
+ |
하나 이상 |
{n} |
n번 반복 |
Charcter | 의미 |
---|---|
\b | 단어 경계 |
\B |
단어 경계가 아님 |
^ |
문자열의 시작 |
$ |
문자열의 끝 |
Charcter | 의미 |
---|---|
\ |
특수 문자가 아닌 문자 |
. |
어떤 글자(줄바꿈 문자 제외) |
\d |
digit 숫자 |
\D |
n번 반복 |
\w |
word 문자 |
\W |
word 문자 아님 |
\s |
space 공백 |
\S |
space 공백 아님 |
swift에서 정규표현식을 사용하는 방법
swift에서 정규표현식을 나타내는 방식은 4가지가 있습니다.
1. 문자열 방식
escape 문자를 사용하기 위해선 \\
처럼 사용해야 합니다.
let pattern = "Hi, WWDC\\d{2}!"
let regex = try Regex(pattern)
2. Raw String 방식
\\
escape 문자를 하나만 사용해도 되도록 해줍니다.
let pattern = #"Hi, WWDC\d{2}!"#
let regex = try Regex(pattern)
3. Regex Literal 방식
Raw String 방식 + 패턴을 regex 타입으로 변환하는 과정이 사라집니다.
let regex = /Hi, WWDC\d{2}!/
4. Regex Builder DSL(Domain Specific Language) 방식
import RegexBuilder
let regex = Regex {
"Hi, WWDC"
Repeat(.digit, count: 2)
"!"
}
Regex Builder 문법 만으론 표현이 부족하다면,
Regex Literal을 섞어서 사용할 수도 있습니다.
let regex = Regex {
/[a-zA-Z][a-zA-Z0-9]*/
"Hi, WWDC"
Repeat(.digit, count: 2)
"!"
}
matching되는 부분 찾기
문자열에서 매치되는 부분을 찾기 위한 메소드는 4가지가 있습니다.
- firstMatch: 첫번째로 regex와 매칭되는 문자열 리턴
- wholeMatch: 전체 문장이 모두 regex와 매칭되는 문자열 리턴
- matches: 매칭되는 모든 문자열 collection 리턴
- Capture: RegexBuilder에서만 지원하는 기능으로 원하는 문자열을 캡쳐
firstMatch, wholeMatch, matches
let pattern1 = "Hi, WWDC\\d{2}!"
let regex1 = try Regex(pattern1)
let firstMatch = input.firstMatch(of: regex1)
let wholeMatch = input.wholeMatch(of: regex1)
let matches = input.matches(of: regex1)
print("firstMatch: \(firstMatch?.output.map { String($0.substring!) } )")
print("wholeMatch: \(wholeMatch?.output.map { String($0.substring!) })")
print("matches: \(matches.map { $0.output.map { String($0.substring!) } })")
// firstMatch: Optional(["Hi, WWDC24!"])
// wholeMatch: nil
// matches: [["Hi, WWDC24!"], ["Hi, WWDC25!"]]
capture
let regex4 = Regex {
"Hi, WWDC"
Capture {
Repeat(.digit, count: 2)
}
"!"
}
let input = "Hi, WWDC24! Hi, WWDC25! I`m Youngkyu"
let firstMatch = input.firstMatch(of: regex4)
let wholeMatch = input.wholeMatch(of: regex4)
let matches = input.matches(of: regex4)
print("firstMatch: \( firstMatch?.output.0 ) \( firstMatch?.output.1 ) ")
print("wholeMatch: \( wholeMatch?.output.0 ) \( wholeMatch?.output.1 ) ")
print("matches: \( matches[0].output.0 ) \( matches[0].output.1 ) ")
// firstMatch: Optional("Hi, WWDC24!") Optional("24")
// wholeMatch: nil nil
// matches: Hi, WWDC24! 24
참고 자료
'부스트캠프' 카테고리의 다른 글
발행-구독 패턴(Publisher-Subscriber Pattern) (0) | 2024.07.25 |
---|---|
함수형 프로그래밍 with. Swift (0) | 2024.07.24 |
Static Dispatch & Dynamic Dispatch (0) | 2024.07.22 |
네이버 부스트캠프 웹・모바일 9기 챌린지 과정 1주차 회고 (0) | 2024.07.19 |
메모리의 구조 (0) | 2024.07.18 |