boraBong

[Swift] Regex, 정규표현식 사용하기 본문

iOS/Swift

[Swift] Regex, 정규표현식 사용하기

보라봉_ 2023. 2. 22. 19:40
728x90

Meet Swift Regex - WWDC22를 보고 추가로 궁금한 부분을 공부하여 정리해보았습니다.

💡 정규표현식이란?

사용자가 규칙을 세워 패턴을 정의해둔 String

정규 표현식은 패턴을 설명하는 간결한 방법으로, 문자열의 일부를 일치시키거나 추출하는 데 도움이 될 수 있습니다. Regex 정규식 리터럴 또는 문자열에서 정규식 구문을 사용하여 인스턴스를 만들 수 있습니다.

⇒ swift에서는 Regex에서 정규표현식 구문을 사용할 수 있다!

 

💡 Regex 만들기

  1. String으로 만들기
let simpleDigits = try Regex("[0-9]+")

 

2.  / / 로 만들기

let keyAndValue = /(.+?): (.+)/ 
// /.../ 패턴 : Regex Literal이라 칭함

→ / / 안에 정규표현식을 써주면 컴파일러가 Regex 타입으로 변환한다.

 

3. RegexBuilder로 만들기

RegexBuilder 모듈을 import하게되면 RegexBuilder를 이용하여 선언적 구문으로 정규표현식을 작성할 수 있다.

import RegexBuilder

let regex = Regex {
    "19"
    Repeat(.digit, count: 2)
}

// let regex = /19[0-9]{2}/ 와 같은 구문

위처럼 Regex에 정규 표현식 패턴을 넣어 사용할 수 있다.

 

💡 정규 표현식 규칙

  • 숫자
    • [0-9]
    • \d
  • 문자(character) : \w (숫자, 글자 모두 포함)
  • 영어
    • [A-Za-z]: 대소문자 모두
  • 한글 [가-힣]
  • 특수문자 [!@#$%^&*()-=+] [!@$%^&+=]
  • 반복
    • + : 앞의 문자가 0번 이상 반복
    • * : 앞의 문자가 1번 이상 반복
    •  
    • (\\w)\\1\\1\\1\\1+ → 5개 이상 글자가 반복될 때
  • 시작과 끝
    • ^ : ~로 시작
    • $ : ~로 끝남
  • 공백
    • \s : space
    • \t : tab
    • \r\n : line break (줄바꿈)
    • \f : form feed
  • 특수기호
    • swift에서는 특수기호 앞에 \가 붙어야 한다.
    • 특히 regex에서 \와 같이 쓰이는 기호는 2개를 붙여 \\로 표현해주어야 한다
      • \. == .
      • \\. == \.
  • 조건문
    • (?=.*
      • (?=.*[A-Za-z]) → 문자열에서 영어가 포함되어 있는지

 

💡 정규 표현식 패턴

let lowercasedAlphabet = /[a-z]{}/

이처럼 [] 안에는 표현식을 이루는 문자 타입을 넣어주면 된다!

뒤의 {} 안에는 String이 몇 자로 이루어지는 패턴을 가지는지를 패턴화해주면 된다.

 

ex. 5자의 소문자로 이루어진 문자열 패턴

let lowercasedAlphabet = /[a-z]{5}/

 

ex. 문자열 길이가 특정 범위 내에서 가변적일 때

let lowercasedAlphabet = /[a-z]{5,}/ // 5글자 이상
let lowercasedAlphabet = /[a-z]{5,10}/ // 5글자 이상 10글자 이하

 

ex. 숫자와 영문자만 포함할 때

let regexPattern = "^[0-9a-zA-Z]*$"
guard let _ = S.range(of: regexPattern, options: .regularExpression) else { return false }
// 숫자와 영문자만 포함되지 않았다면 false를 반환

 

 

💡 자주 사용되는 정규표현식

  • 이메일
let emailRegex = /[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}/

 

  • 휴대폰 번호
let phoneNumberRegex = /^01[0-1, 7][0-9]{7,8}$/

 

  • 비밀번호 (영문 대문자, 소문자, 숫자, 특수문자만 허용 8 ~20자 사이)
let pwRegex = /[A-Za-z0-9!_@$%^&+=]{8,20}/

 

let yearRegex = /19[0-9]{2}|20[0-9]{2}/

 

let monthRegex = /0[1-9]|1[0-2]/

 

let dayRegex = /0[1-9]|1[0-9]|2[0-9]|3[0-1]/

 

💡 정규표현식 응용

  • firstMatch(of:) - 컬렉션 내에서 지정된 정규식의 첫 번째 일치 항목을 반환합니다.
    • Return Value
      • 일치 항목 있는 경우: regex 컬렉션의 첫 번째 일치 항목 반환
      • 일치 항목 없는 경우: nil
  • wholeMatch(of:) - 이 문자열이 전체에서 지정된 정규식과 일치하는 경우 일치 항목을 반환합니다.
    • Return Value
      • 일치 항목 있는 경우: 일치 항목 반환
      • 일치 항목 없거나 변환에서 regex 오류 발생시: nil
  • prefixMatch(of:) - 이 문자열이 처음에 지정된 정규식과 일치하는 경우 일치 항목을 반환합니다.
    • Return Value
      • 일치 항목 있는 경우: 일치 항목 반환
      • 일치 항목 없거나 변환에서 regex 오류 발생시: nil
    • firstMatch(of:) 와의 차이점: prefixMatch는 시작지점부터 일치하는지를 반환하는 것이고 firstMatch는 일치하는 첫번째 항목을 반환하는 것이다.
  • matches(of:) - 지정된 정규식과 일치하는 모든 항목을 포함하는 컬렉션을 반환합니다.
    • Return Value
      • 정된 정규식과 일치하는 모든 항목을 포함하는 Regex<Output> 컬렉션 → mapping 필요

 

📍 firstMatch(in: ), wholeMatch(in: ) - 정규식을 기준으로 문자열이 일치하는지를 파악

  • 즉, of 내에는 정규식 대입
  • in 내에는 문자열 대입

 

✅ 문자열에서 첫번째로 일치하는 부분 반환

🔑 firstMatch를 사용하자

let input = "18292022"
let regex = /19[0-9]{2}|20[0-9]{2}/
let match = input.firstMatch(of: regex)?.output 
// 2022

 

👉🏻 prefixMatch를 사용해본다면?

let input = "18292022"
let regex = /19[0-9]{2}|20[0-9]{2}/
let match = input.prefixMatch(of: regex)?.output 
// nil

→ 시작지점에서 정규식과 일치하지 않으므로 nil을 반환한다.

 

 

👉🏻 input값을 20221829로 바꾸어본다면?

let input = "20221829"
let regex = /19[0-9]{2}|20[0-9]{2}/
let match = input.prefixMatch(of: regex)?.output 
// 2022

→ 접두 부분인 시작점이 정규식 부분과 일치하므로 일치하는 부분이 잘 반환되는 것을 확인할 수 있다.

 

✅ 문자열 전체가 regex와 일치하는지 반환

🔑 wholeMatch를 사용하자

let input = "20221829"
let regex = /19[0-9]{2}|20[0-9]{2}/
let match = input.wholeMatch(of: regex)?.output 
// nil

 

✅ 문자열에서 regex와 매칭(일치)하는 모든 부분 반환

🔑 matches를 사용하자

let input = "20221929"
let regex = /19[0-9]{2}|20[0-9]{2}/
let match = input.matches(of: regex).map{ $0.output } 
// ["2022", "1929"]

 

✅ 문자열에서 정규식과 일치하는 개수 파악

🔑 matches를 사용하자

let input = "20221929"
let regex = /19[0-9]{2}|20[0-9]{2}/
let cnt = input.matches(of: **regex**).count 
// 2

 

 

<참고>

[Swift] Swift에서 다양한 정규표현식(Regular Expression) 사용해보기

[Swift] 코딩테스트 보다가 열 받아서 정리하는 Swift 정규식 - NSRegularExpression (Regex)

Swift Regex

Apple Developer Documentation

Apple Developer Documentation

Meet Swift Regex - WWDC22 - Videos - Apple Developer

Regular Expression : Swift 에서 정규표현식 사용 - NSRegularExpression

반응형

'iOS > Swift' 카테고리의 다른 글

[Swift] Swift 고차함수 문법 - Map, Filter, Reduce  (0) 2023.01.08
[Swift] 구조체와 클래스  (1) 2022.04.15
[Swift] 함수형 프로그래밍이란?  (0) 2020.12.08
Comments