[Swift5] Strings and Characters 2

12749 단어 swiftswift

Strings and Characters

문자열 접근 및 수정

문자열이 제공하는 메소드와 프로퍼티를 통해 문자열 데이터에 접근하거나 수정할 수 있다.

문자열 인덱스

  • 문자열 값은 String.Index를 통해 각 캐릭터에 접근할 수 있다.

스위프트는 캐리터마다 서로 다른 메모리 공간을 지원하기 때문에 정수 값을 통해 인덱스에 접근할 수 없다. 따라서 어떤 캐릭터가 어떤 위치에 있는지 구하려면 유니코드 스칼라를 처음이나 끝에서 반복해가면서 구해야 한다.

  • 문자열의 처음 캐릭터 값은 String.startIndex를 통해 접근할 수 있다.

  • String.endIndex은 문자열의 마지막 캐릭터가 있는 좌표가 아니라, 그 다음 좌표다.

endIndex 프로퍼티가 문자열 내 끝 인덱스 + 1 위치임을 주의하자

따라서 만일 문자열이 없다면(=비었다면) startIndex와 endIndex는 같다.

  • 문자열의 인덱스 메소드 index(before: ), index(after: ), index(_:offsetBy:)를 통해 문자열에 접근하자.
let greeting = "Hello, Swift!"
print(greeting[greeting.startIndex])
// "H"
print(greeting[greeting.index(before: greeting.endIndex)])
// "!"
print(greeting[greeting.index(after: greeting.startIndex)])
// "e"
let idx = greeting.index(greeting.startIndex, offsetBy: 7)
print(greeting[idx])
// "S"

다른 프로그래밍 언어와 같이 주어진 문자열 인덱스를 초과하지 말자.

  • String.indices 프로퍼티를 통해 주어진 문자열의 인덱스를 얻을 수 있다. for 문과 같이 쓰자.

삽입과 삭제

  • String.insert(_:at:) 메소드로 특정 인덱스에 캐릭터를 삽입할 수 있다.

  • String.insert(contentsOf:at:) 메소드로 문자열을 삽입할 수 있다.

var  greeting = "Hello"
greeting.insert(",", at: greeting.endIndex)
// "Hello,"
greeting.insert(contentsOf: " Swift!", at: greeting.endIndex)
// "Hello, Swift!"
  • String.remove(at:) 메소드로 특정 인덱스의 캐릭터를 삭제할 수 있다.

  • String.removeSubrange(_:) 메소드로 문자열을 삭제할 수 있다.

var  greeting = "Hello, Swift!"
greeting.remove(at: greeting.index(before: greeting.endIndex))
// "Hello, Swift"
let range = greeting.index(greeting.endIndex, offsetBy: -7)..<greeting.endIndex
greeting.removeSubrange(range)
// "Hello"

스위프트의 문자열 인덱스 접근 방법이 다소 낯선데, 익숙해지도록 많이 사용해보자.

부분 문자열

스위프트는 문자열의 일부를 자르거나 따로 담은 부분 문자열 클래스를 지원한다. 이 부분 문자열은 일반적인 문자열과 같은 메소드와 프로퍼티를 지원하지만, 오랫 동안 사용하려면 문자열 인스턴스로 변환할 필요가 있다.

let greeting = "Hello, Swift!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"

// Convert the result to a String for long-term storage.
let newString = String(beginning)

위 예시처럼 beginning이라는 부분 문자열만 사용해도 원하는 값을 얻어내는 것처럼 보이지만, 스위프트는 부분 문자열을 바로 문자열로 변환해 담아두라고 조언한다.

부분 문자열 클래스는 퍼포먼스 최적화를 위해 원본 문자열(부분 문자열이 복사하거나 자른 원본)이 사용하는 메모리 공간을 재사용하기 때문이다.

문자열 비교

문자열과 캐릭터 비교

  • ==, != 연산자로 두 문자열 또는 캐릭터가 같은지 여부를 확인할 수 있다.

이때 비교되는 확장된 문자소 클러스터가 정확히 똑같은 유니코드 스칼라 값으로 구성되어 있지 않더라도 언어적으로 같은 의미와 모양일 때에는 같다고 판단한다. é = e + ´이므로 왼쪽 유니코드 값 U+00E9를 넣든, 오른쪽 유니코드 U+0065, U+0301 두 개 를 넣든 동일하다는 말이다.

반대로 모양이 같더라도 언어적으로 뜻이 다르다면 False를 반환한다. 예를 들어 A(U+0041) != А(U+0410).

접두사와 접미사 비교

  • String.hasPrefix(_:), String.hasSuffix(_:) 메소드를 통해 문자열에 특정한 문자열이 접두사/접미사로 들어 있는지 확인한다.

문자열 배열을 만들고, 접두사 또는 접미사가 공통적으로 들어 있는 경우를 확인해보자.

let romeoAndJuliet = [
    "Act 1 Scene 1: Verona, A public place",
    "Act 1 Scene 2: Capulet's mansion",
    "Act 1 Scene 3: A room in Capulet's mansion",
    "Act 1 Scene 4: A street outside Capulet's mansion",
    "Act 1 Scene 5: The Great Hall in Capulet's mansion",
    "Act 2 Scene 1: Outside Capulet's mansion",
    "Act 2 Scene 2: Capulet's orchard",
    "Act 2 Scene 3: Outside Friar Lawrence's cell",
    "Act 2 Scene 4: A street in Verona",
    "Act 2 Scene 5: Capulet's mansion",
    "Act 2 Scene 6: Friar Lawrence's cell"
]

var act2SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 2 ") {
        act2SceneCount += 1
    }
}
// act2SceneCount: 6

유니코드 표현

유니코드 문자열이 텍스트 파일 등에 쓰이면 유니코드 스칼라 값이 유니코드 인코딩 형태 중 하나로 인코딩된다. 문자열은 코드 유닛이라 불리는 작은 블록으로 조각나 인코딩되는데, 이 코드 유닛 크기에 따라 다른 인코딩 형태를 가진다.

UTF-8

  • String.uft8 프로퍼티로 접근한다.
let dogString = "Dog‼🐶"
for codeUnit in dogString.utf8 {
    print("\(codeUnit) ", terminator: "")
}
// 68 111 103 226 128 188 240 159 144 182

UTF-16

  • String.utf16 프로퍼티로 접근한다.
let dogString = "Dog‼🐶"
for codeUnit in dogString.utf16 {
    print("\(codeUnit) ", terminator: "")
}
// 68 111 103 8252 55357 56374

유니코드 스칼라

  • String.unicodeScalars 프로퍼티로 접근한다.
let dogString = "Dog‼🐶"
for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ", terminator: "")
}
// 68 111 103 8252 128054

스위프트가 지원하는 유니코드 스칼라 값은 UTF-32와 같다. 각 유니코드 인코딩 형태가 지원 가능한 비트 수로 바로 표현이 가능하다면 그렇게, 크다면 나눠서 표현되는 것을 볼 수 있다.

좋은 웹페이지 즐겨찾기