Swift - 문자열(String)
문자열은 일반적으로 문자(Character)가 2개 이상 모여서 이루어진 사람이 인식하기 위한 글자를 모두 표현하는 String 타입을 의미한다. 그냥 대충 더블쿼터로 묶인 "블라 블라" 이런거다. -_-;; (참고로 이 글은 Swift 4 기준으로 수정되었다)
문자열의 정의는 위에서 이야기 한 것 처럼 문자열로 표시하기만 하면 알아서 타입이 String으로 만들어진다.
바이트 크기를 알고 싶을 때를 위해 lengthOfBytes(using:) 메소드를 제공한다. 이름에서 보듯이 특정 인코딩을 이용해 길이를 알려주는 메소드다.
이번에는 문자열의 구성 단위인 Character를 이용해 문자열을 만들어 보자
Swift의 문자열은 특별한 포매팅 방법을 제공한다. 영어로 String Interpolation 이라는 기능이다.
물론 전통적인 기존 방식을 못 쓰는 것은 아니지만, 스위프트 고유가 아닌 NSString의 힘을 빌려써야 한다.
덕분에 이런 문자열 비교를 switch - case 문에서도 활용이 가능하다는 건 정말 편한 것 같다.
이전에는 substring 같은 메소드가 있기는 있었지만 deprecated 되었으니 이제는 이런 방식을 쓰면 된다.
[관련글] Swift - 옵셔널(Optionals)
[관련글] Swift - 오퍼레이터 오버로드(Operator Overloads)
[돌아가기] 스위프트(Swift) 가이드
문자열의 정의는 위에서 이야기 한 것 처럼 문자열로 표시하기만 하면 알아서 타입이 String으로 만들어진다.
let someString = "This is string." var otherString = "Mutable String"물론 String 클래스를 이용해 생성하는 것도 가능하다.
let someString2 = String("This is string 2.")빈 문자열도 생각나는 대로 적으면 되긴 된다.
var emptyString1 = "" var emptyString2 = String() var emptyString3 = String("")String 클래스에서 더하기 연산자(+)는 문자열을 연결시키는 용도로 사용 할 수 있다. 마치 Python 처럼...
var concatString = "LEFT " + "RIGHT" // "LEFT RIGHT" concatString += " END" // "LEFT RIGHT END"이 '+' 연산자를 이용하면 NSString 을 이용 할 때의 지옥이 사라진다. 환상적이다.
문자열의 길이
다짜고짜 예제부터 보자."SOME STRING".characters.count위 코드는 10 이라는 숫자를 돌려준다. 그런데 이 코드는 아래처럼 더 축약이 가능하다.
"SOME STRING".count둘 다 같다고 생각하자. 이름만 봐도 대충 유추가 가능한 이 프로퍼티는 유니코드 기준 문자의 갯수를 알려준다.
바이트 크기를 알고 싶을 때를 위해 lengthOfBytes(using:) 메소드를 제공한다. 이름에서 보듯이 특정 인코딩을 이용해 길이를 알려주는 메소드다.
var s = "test" s.lengthOfBytes(using: .utf8) // 4UTF-8인코딩을 기준으로 영문자의 경우 문자의 갯수를 잘 알 수 있다. 하지만 한글 등 멀티바이트 문자를 사용하게 되면 오해(?)를 불러오는 결과를 초래한다.
s = "한글" s.lengthOfBytes(using: .utf8) // 6 s.lengthOfBytes(using: .utf16) // 4메소드 이름이 '바이트의 길이' 라는 점에 유의해야 한다. 그래서 유니코드의 경우 인코딩에 따라 다른 결과를 돌려준다. 따라서 한국인인 우리가 원하는 결과가 아니다라는 것을 알아둬야 한다. 한글 등 현대적인 유니코드 기반의 길이를 원한다면 앞서 살펴본 .count 프로퍼티를 이용하자.
이번에는 문자열의 구성 단위인 Character를 이용해 문자열을 만들어 보자
var hc1 = Character("한") var hc2 = Character("글") s = hc1 + hc2 // "한글"이번에는 시험삼아 문자열 이터레이션도 해보자.
for ch in "새로운한글" { println(ch) }위의 결과는 콘솔에 새/로/운/한/글 각 한 글자를 한 라인씩 출력한다. 여기서 ch의 타입은 Character 이다. String이 Character의 모임이라는 것을 알 수 있다. 제일 처음 문자 갯수를 세는 예제에서 .characters 라는 프로퍼티를 참고하는 것을 생각해보면 연관관계가 보일 것이다.
문자열 포매팅
포매팅이라는 표현은 C의 printf 나 sprintf 등에서 사용하는 방식과 비슷하다. %s 자리에 특정 문자열을 대체하는 것 처럼 말이다. Objective-C 라면 NSString의 stringWithFormat 메소드에 해당한다.Swift의 문자열은 특별한 포매팅 방법을 제공한다. 영어로 String Interpolation 이라는 기능이다.
var a = 1 var b = "TEST" var c = 5.6 var someString = "a = \(a), b = \(b), c = \(c)" // someString = "a = 1, b = TEST, c = 5.6"괄호와 괄호 앞에 백슬래쉬(\)를 붙여서 문자열의 내용과 포함시킬 내용을 구분한다. 마치 Python의 format과 비슷하다. 하지만 Swift의 문자열 대치 커맨드는 좀 더 확장된 기능을 제공하는데 여기다 그냥 Swift 코드를 적어 넣을 수도 있다.
var someString2 = "2 + 6 = \(2 + 6)" // someString2 = "2 + 6 = 8"2 + 6 이라는 결과가 그대로 문자열로 변경되어서 해당 위치로 쏘옥 들어간다. 즉 \() 내용 안에 들어있는 코드가 실행된 결과가 문자열로 변경되어 들어간다는 말이다. 이건 정말 편하다.
물론 전통적인 기존 방식을 못 쓰는 것은 아니지만, 스위프트 고유가 아닌 NSString의 힘을 빌려써야 한다.
let s = String(format: "%04d", arguments: [10]) // s = "0010"어느 순간부터 NSString 자체의 기능이 String 라는 이름으로 쓸 수 있게 되었다. 친절해졌다.
문자열의 비교
일반적으로 비교 시 사용하는 논리 연산자(Logical Operator)를 String 타입에 거의 비슷한 용도로 활용이 가능하다."AAA" == "BBB" // false "CCC" != "DDD" // true "EEE" == "EEE" // true "AAA" > "BBB" // false "CCC" > "BBB" // true스위프트는 포인터를 문법에서 배제한 언어다. '==' 등등으로 비교하는게 레퍼런스 포인터 간의 비교가 아니라 실제 데이터 비교 (정확히 표현하자면 비교연산자를 오퍼레이터 오버로딩) 이다.
덕분에 이런 문자열 비교를 switch - case 문에서도 활용이 가능하다는 건 정말 편한 것 같다.
검색
문자열에서 특정 문자열을 검색하는 건 range(of:) 메소드를 이용해서 가능하다.s = "ABCDE" let range = s.range(of: "C") // Range s[range] // "C"range(of:) 메소드의 결과값은 Range 타입인데 구성요소는 String.Index 라는 특수한 타입으로 되어있어서 C처럼 정수형으로 처리하는 것은 아예 생각하지 말자. 그래도 뭔가 정보를 얻고 싶다면 Range 에서 제공하는 lowerBound 와 upperBound 라는 프로퍼티 값을 잘 살펴보자.
일부만 가져오기(substring)
String 의 subscript 를 이용해 문자열을 슬라이싱 하는 방법은 아래왁 같다.var str = "this is test string" let lowerBound = String.Index(encodedOffset: 5) let upperBound = String.Index(encodedOffset: 6) str[lowerBound...upperBound] // "is"Swift 의 Range 를 이용해 문자열의 subscript 를 이용하면 문자열의 일부를 잘라낼 수 있다. 다만 앞서 검색과 비슷하게 String.Index 라는 타입을 이용해 범위(Range) 를 만들어서 이를 subscript 하는 귀찮은 점이 있다.
이전에는 substring 같은 메소드가 있기는 있었지만 deprecated 되었으니 이제는 이런 방식을 쓰면 된다.
앞 뒤 공백 잘라내기(Trim)
살짝 좀 귀찮은 방법으로 Trim 기능을 이용 할 수 있다.let someString = " Blah blah foo bar " someString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) // "Blah blah foo bar"아이고 귀찮아. 그냥 .trim() 같은거 만들어 주면 안되겠나?! 라고 생각된다면 그냥 extension 으로 만들면 된다. ;-)
기타 기능들
String 타입도 많은 기능이 있는데 이 중 유용할 것 같은 프로퍼티와 메소드만 간추려본다:- isEmpty(): 빈 문자열이면 true
- hasPrefix("..."): 특정 문자열로 시작하면 true
- hasSuffix("..."): 특정 문자열로 끝나면 true
- uppercased(): 몽땅 대문자로 바꾼 문자열
- lowercased(): 몽땅 소문자로 바꾼 문자열
let integerValue = Int(someString)위의 예제에서 만약 변환이 실패하면 nil 이 돌아오니 옵셔널을 확인하는 것을 잊지 말자.
[관련글] Swift - 옵셔널(Optionals)
[관련글] Swift - 오퍼레이터 오버로드(Operator Overloads)
[돌아가기] 스위프트(Swift) 가이드
댓글
문자열 포매팅에서 NSString(format 과 유사하기
println(String(format: "hex string: %X", 123456))
println(String(format: "a float number: %.5f", 1.0321))
String(format: 이라는 방법도 있네요.
네. 해당 글을 쓸 당시에는 Swift String에 NSString Bridge가 자동으로 되지 않던 시절이라 그렇습니다만 현재(1.2)는 자동으로 브릿지 매핑이 되어 있습니다.
그런데 Xcode7 Beta 5(Swift 2.0 Beta)에서 NSString Bridge가 다시 사라져 버렸습니다. 어떻게 될지 알 수가 없네요. ;;;;