[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🍎 Apple/Swift

[Swift] 문자열 처리

inu 2022. 1. 22. 23:58
반응형

코딩테스트의 주력 언어를 Swift로 변경하고나서 가장 번거롭게 느껴진 것은 문자열 처리였다. 문자열 처리가 쉬운 다른 언어와는 다르게 참 복잡하다고 생각했다.

 

하지만 그래도 정리하고 사용하다보면 금방 적응될 것이라고 생각한다.

그래서 개인적으로 번거로웠던 부분을 정리해놓는다. (새로운 팁을 알게되면 지속적으로 업데이트 예정)


문자열에 하나씩 접근하면 Character 타입으로 받아온다

파이썬은 for문을 활용해 접근했을 때 각 문자를 str형태로 받아온다.
하지만 Swift는 각 요소를 Character 타입으로 받아온다.

let str = "Hello"
for c in str {
    print("\(type(of: c)")
}

// Character
// Character
// Character
// Character
// Character

문자열 결합, 비교가 가능하다

let a = "a"
let b = "b"
print(a + b) // "ab"

let a = "a1"
let b = "a1"
print(a == b) // true

인덱스 접근은 String.index를 활용해야 한다

보통 파이썬과 같은 언어에서는 str[0]와 같이 쉽게 인덱스에 접근할 수 있었다.
하지만 Swift는 인덱스 접근에 String.index를 활용해야 한다.

  • startIndex : 문자열의 시작 요소 인덱스 반환
  • endIndex : 문자열의 마지막 요소 인덱스 반환
  • index(before: String.Index) : 인자로 들어온 인덱스
  • index(after: String.Index) : 인자로 들어온 인덱스
  • index(String.Index, offsetBy: String.IndexDistance) : 인자로 들어온 인덱스와 offsetBy 차이만큼 떨어진 인덱스 반환
  • firstIndex(of: Character) : 인자로 들어온 문자가 처음으로 존재하는 인덱스 반환 (Optional)
  • lastIndex(of: Character) : 인자로 들어온 문자가 마지막으로 존재하는 인덱스 반환 (Optional)
let str = "abcdefg"
print(str[str.startIndex]) // a
print(str[str.index(after: str.startIndex)]) // b
print(str[str.index(before: str.endIndex)]) // g
print(str[str.index(str.startIndex, offsetBy: 2)]) // c
print(str[str.index(str.endIndex, offsetBy: -2)]) // f

subscript(_ index: Int)를 extension으로 등록해놓으면 좀 더 편하게 접근할 수 있다.

extension String {
    subscript(_ index: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: index)]
    }
}

let str = "abcde"
print(str[3]) // d

String.index의 Range를 사용하면 Substring가 얻어진다

파이썬에서 range를 활용해 부분적인 String을 반환했던 것처럼 Swift에서도 String.index의 Range를 사용하면 부분적인 String을 얻을 수 있다.


그런데 파이썬과 다르게 반환되는 타입이 Substring으로 변한다.

let str = "abc def"
let firstSpace = str.firstIndex(of: " ") ?? str.endIndex
let substr = str[..<firstSpace]
print(substr) // abc
print(type(of: substr)) // Substring

Substring은 원본 문자열의 인스턴스를 참조하여 만들어진다. 그래서 메모리 효율은 좋지만, 변형이 필요할 경우 String으로 형변환을해서 새로운 객체를 생성하는 것이 좋다.

 

이 역시 extension을 활룡해 좀 더 쉽게 처리할 수 있다.

extension String {
    subscript(_ range: Range<Int>) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: range.startIndex)
        let toIndex = self.index(self.startIndex,offsetBy: range.endIndex)
        return String(self[fromIndex..<toIndex])
    }
}

let str = "abcde"
print(str[0..<4]) // abcd

prefix, suffix를 활용해 접두어 및 접미사를 확인할 수 있다

let str = "abcdef"

print(str.prefix(3)) // abc
print(str.prefix(4)) // abcd

print(str.suffix(1)) // f
print(str.suffix(2)) // ef

hasPrefix와 hasSuffix를 활용해 접두어 및 접미사의 존재여부를 확인할 수 있다

let str = "abcdef"

print(str.hasPrefix("a"))  // true
print(str.hasPrefix("ab")) // true
print(str.hasPrefix("ba")) // false

print(str.hasSuffix("f"))  // true
print(str.hasSuffix("ef")) // true
print(str.hasSuffix("fe")) // false

대소문자 치환 메서드를 제공한다

let str = "AbCdEfG"
print(str.uppercased()) // "ABCDEFG"
print(str.lowercased()) // "abcdefg"

Charater 타입에서는 아스키코드를 불러올 수 있다

let str = "abcde"
for c in str {
    var ascii = c.asciiValue!
    var char = Character(UnicodeScalar(ascii))
    print(ascii)
    print(char) 
}

// 97
// a
// 98
// b
// 99
// c
// 100
// d
// 101
// e

replacingOccurrences를 통해 쉽게 치환할 수 있다

let str = "abcde"
let newStr = str.replacingOccurrences(of: "ab", with: "zzzzzzz")
print(newStr) // zzzzzzzcde

isLetter, isNumber, isUppercase 등 Character의 타입을 쉽게 확인할 수 있는 메서드가 존재한다.

import Foundation

let str = "a1b2"
for c in str {
    print(c.isNumber)
}

// false
// true
// false
// true
반응형

'🍎 Apple > Swift' 카테고리의 다른 글

[Swift] Property Wrapper  (0) 2022.02.24
[Swift] Copy on write  (2) 2022.01.26
[Swift] NSCache와 NSDictionary의 차이점  (0) 2022.01.22
[Swift] UserDefaults와 Codable, NSCoding  (2) 2022.01.01
[Swift] Dynamic Dispatch 줄이기  (0) 2021.12.16