String And Characters
문자열(String)은 ""로 묶어서 표현한다.
let str = "String" // 문자열
var char = "C" // 문자열
var char1: Character = "C" // 문자
type(of: char) // String.Type
type(of: char1) // Character.Type
" "안에 문자 하나만 들어있다고 해서 문자열이 아니며 문자(Character)타입으로 선어해주려면 Character로 선언해주어야 한다.
빈 문자열
// "" 안에 공백이 없으면 문자열로 추론되므로 문자타입으로 바꿀수 없다고 에러가 발생한다.
let emptyChar: Character = " " // 빈문자 저장
let emptyStr = " " // 공백이 1개인 문자열 빈문자열이 아니다.
let emptyStr1 = "" // 공백이 없어야 빈문자열이다.
String Type
Swift에서는 2개의 문자열 자료형을 사용한다.
1. String - 구조체, 값 형식으로 구성 (Swift String)
2. NSString - 클래스, 참조 형식으로 처리 가능 (Foundation String)
두 형식은 서로 호환되며, 저장할 때는 Type Casting(as)을 해주어야 한다.
유니코드를 처리하는 방식은 서로 다르기 때문에 조심해야 한다.
var nsStr: NSString = "Swift"
var swiftStr: String = nsStr as String // as(Type Casting)
nsstr = swiftStr as NSString
문자열의 가변성 (Mutablilty)
let immutableStr = "str"
immutableStr = "Swift" // 상수로 선언되어 있으므로 에러 발생
var Mutable = "str"
Mutable = "Swift" // 변수로 선언되어 있으므로 정상적으로 변경
Unicode
var unicodeTest = "📝"
var unicodeTest1 = "\u{1F4DD}" // "📝"
// 📝 유니코드: U+1F4DD, UTF-8: F0 9F 93 9D
"\u{ }" 안에 U+를 제외한 값을 넣어주면 유니코드를 출력할 수 있다.
Multiline String Literals
코드에서 여러 줄의 문자열을 표현할 수 있다.
let str = "abcdefg" // Single-line
let str2 = "123456789 \n 0987654321" // \n 줄바꿈
// Multiline String
let mulStr = """
123456789
abcdefghi
0987654321
"""
// 들여쓰기
let mulStr2 = """
123456789
abcdefghi
0987654321
"""
// 에러나는 경우
let mulStr3 = """
123456789
abcdefghi
0987654321
""" // <<< 이렇게 아래 """ 위치가 오른쪽에 위치하면 실행되지 않는다.
// 멀티라인에서 문자열 이어서 사용하기
let mulStr4 = """
123456789 \ <<< \백슬레시 사용시 첫번째 줄과 두번째 줄이 이어져서 나온다.
abcdefghi
0987654321
"""
Raw String
\, "를 문자 자체로 처리한다.
문자열 안에서 ""를 사용하려면 "앞에 \를 추가한다.
Raw String으로 만들려면 문자열 Literal 양쪽 끝을 # #으로 감싸면 된다.
Raw String으로 처리한 문자열에 \n이 포함되어 있다면 \뒤에 #을 붙인다.
var str = "\"hello\", Swift" // "hello", Swift
var rawStr = #"\"hello\", Swift"# // \"hello\", Swift 그대로
var str1 = "hello, \n Swift" // hello,
// Swift
var rawStr1 = #"hello, \n Swift"# // hello, \n Swift 그대로
//Raw String에서 \n을 사용하고싶을땐
var rawStr2 = #"hello, \#n Swift"# // hello,
//Swift
//Raw String에 # 여러개 사용가능하지만 갯수를 맞춰야한다.
var rawStr3 = ###"hello, \###n Swift"### //hello,
//Swift
String Interpolation
문자열 삽입, 문자열 보간이라고 한다.
기본 문법
\()
//문자열 보간을 사용하지 않았을 경우
var weight = "60kg"
let kg = 60
var result = String(kg) + "kg"
print(result) // 60kg
// 문자열 보간 사용했을 경우
print("\(kg)Kg") // 60kg
문자열 포멧 생성자 (Format Specifier)
var size = 12.34
var str = String(format: "%.1f", size) // 12.3
String(format: "hello, %@", "swift") // "hello, swift"
String(format: "%d", 12) // 12
String(format: "%f", 12.34) // 12.340000
String(format: "%.3f", 12.34) // 12.340
String(format: "%10.3f", 12.34) // 12.340
String(format: "%010.3f", 12.34) // 000012.340
String(format: "[%d]", 123) // [123]
String(format: "[%10d]", 123) // [ 123] 오른쪽 정렬
String(format: "[%-10d]", 123) // [123 ] 왼쪽 정렬
포멧 지정자
let firstName = "P"
let lastName = "KW"
let eng = "his name is %@ %@."
let kor = "그의 이름은 %2$@ %1$@ 입니다."
String(format: eng, firstName, lastName) // "그의 이름은P KW 입니다."
String(format: kor, firstName, lastName) // "his name is KW P."
Escape Sequence
Escape Character가 앞에 붙은 문자열로 이 문자는 문자 그대로 표현되지 않고 컴파일러에 의해 다른 문자로 변환된다.
| Escape sequence | meaning |
| \0 | null 문자 |
| \t | 문자와 문자사이 탭 |
| \n | 줄바꿈 |
| \" | 큰 따옴표 |
| \' | 작은 따옴포 |
| \u{} | 임의의 유니코드 스칼라 값 |
String Indices (String Index)
첫번째 인덱스를 얻고싶으면 .startIndex로 얻을 수 있으며, 마지막 인덱스를 얻고 싶으면 .endIndex로 얻을 수 있다.
하지만 .endIndex로 마지막 인덱스를 얻고자 할때 에러가 발생하는데 .endIndex는 마지막 인덱스의 다음 인덱스를 가리키기 때문에 인덱스 범위에서 벗어나 에러가 발생한다.
마지막 인덱스를 에러 없이 얻으려면 index(before:) 메소드를 사용해야 한다.
var str = "Swift"
let first = str[str.startIndex]
print(first)
//let last = str[str.endIndex] // 에러 발생
endIndex는 마지막 인덱스가 아니라 마지막 인덱스의 다음 인덱스를 가리킨다.
그래서 마지막 문자에 접근하려면 endIndex의 이전 인덱스가 필요하다. -1 빼기는 불가능하다.
let lastCharIndex = str[str.index(before: str.endIndex)]
print(lastCharIndex) // t
let second = str[str.index(str.startIndex, offsetBy: 1)]
print(second) // w
let third = str[str.index(str.startIndex, offsetBy: 2)]
print(third) // i
second 상수는 index(_:offsetBy:)를 사용해서 "Swift"의 첫번째 인덱스 "S"를 기준으로 1칸 앞에 있는 인덱스 값을 리턴한다.
third 상수는 index(_:offsetBy:)를 사용해서 "Swift"의 첫번째 인덱스 "S"를 기준으로 2칸 앞에 있는 인덱스 값을 리턴한다.
String Basics
문자열을 생성할 때는 ""를 사용하는 방법과 String() 생성자를 사용하는 방법이 있으며 대소문자를 구분하여 비교도 가능하다.
let str = "AAAAAA"
String(repeating: "A", count: 10) // "AAAAAAAAAA"
만약 문자열을 반복적으로 사용하려면 두번째 줄의 코드를 이용하면 된다.
let str = "Swift"
let lowerStr = "swift"
str.count // 5
str.isEmpty // flase
str.lowercased() // "swift"
str.uppercased() // "SWIFT"
lowerStr.capitalized // "Swift"
lowerStr.randomElement() // "s" 랜덤으로 값을 가져옴
lowerStr.shuffled() // ["i", "w", "t", "f", "s"]
.count
문자열의 길이를 리턴해준다.
.isEmpty
문자열이 비어있는지 확인하여 true, false를 리턴해준다.
.lowercased()
문자열의 모든 문자를 소문자로 바꿔 리턴해준다.
.uppercased()
문자열의 모든 문자를 대문자로 바꿔 리턴해준다.
.capitalized
문자열에서 첫번째 문자를 대문자로 바꿔 리턴해준다.
.randomElement()
문자열에서 랜덤으로 하나의 값을 리턴해준다.
.shuffled()
문자열을 랜덤으로 섞어서 문자배열로 리턴해준다.
SubString
하나의 문자열에서 특정 범위에 있는 문자열을 말하며 Copy-On-Write에 최적화 되어있어 값을 읽기만 한다면 원본 문자열의 메모리를 공유하고 값을 변경하는 시점에만 새로운 메모리가 생성되어 저장되므로 불필요한 복사와 메모리 사용을 줄여 성능을 향상 시킨다.
let str = "hello, Swift"
var first = str.prefix(1)
first.insert("!", at: first.endIndex)
print(str) // "hello, Swift"
print(first) // "h!"
insert메소드를 통해 값 변경이 이루어졌지만 결과적으로 원본 str 문자열은 바뀌지 않았다.
값을 변경하는 시점에만 새로운 메모리를 생성하여 사용하는것을 볼수 있다.
// 처음 두개의 문자만 추출하고 싶을 때
let str = "hello, Swift"
let str = str[str.startIndex ..< str.index(str.startIndex, offsetBy: 2)]
let str = str[..<str.index(str.startIndex, offsetBy: 2)]
s // he
let lower = str.index(str.startIndex, offsetBy : 2)
let upper = str.index(str.startIndex, offsetBy : 6)
let str1 = str[lower ... upper] //
print(str1) // "llo, "
String Editing
Appending Strings and Charaters
.append 메소드를 사용하여 문자열을 연결할 수 있다.
- .append 메소드의 리턴형은 Void로 반드시 변수로 사용해야한다.
- .appending 메소드의 리턴형은 String으로 상수에서도 사용 가능하다.
var str = "Hello"
str.append(",")
print(str) // "Hello,"
let str1 = str.appending("Swift")
print(str1) // "Hello, Swift"
append는 대상문자열을 직접 변경하기 때문에 append 메소드 실행 후 str을 출력해보면 "Hello,"가 리턴되고, appeding 대상문자열을 직접 변경하지 않고 새로운 문자열을 리턴하기 때문에 appending 메소드 실행 후 str을 출력해보면 "Hello,"뒤에 "Swift"가 붙지 않는다.
append 처럼 값을 직접 변경하는 메소드에서는 값을 반드시 변수에 선언 해야한다.
var str = "Hello Swift"
str.insert(",", at: str.index(str.startIndex, offsetBy: 5))
if let sIndex = str.firstIndex(of: ",") {
str.insert(contentsOf: "!!!!!!", at: sIndex)
}
위 코드에서 firstIndex의 타입을 보면 String.Index? 옵셔널로 리턴된다. 값이 없으면 nil이 반환되기때문에 옵셔널 바인딩을 해주어야 한다.
Replacing SubStrings
.replaceSubrange 메서드로 문자열을 교체할 수 있으며 .range(of:) 메소드로 교체할 대상 즉, 교체할 문자열을 검색한다.
// 456 -> 789로 교체
var str = "123-456"
if let range = str.range(of: "456") {
str.replaceSubrange(range, with: "789") // 원본값 변경 O
}
str // "123-789"
// 123 -> 456으로 교체
if let range = str.range(of: "123") {
let s = str.replacingCharacters(in: range, with: "456") // 원본값 변경 X
s // "456-789"
str // "123-789"
}
// 123-789 -> "Hello, Swift"로 교체
var s = str.replacingOccurrences(of: "123-789", with: "Hello, Swift") // 원본값 변경X
s // "Hello, Swift"
str // "123-789"
// Swift -> hi로 교체
var str1 = "Hello, Swift"
var ss = str1.replacingOccurrences(of: "swift", with: "hi", options: [.caseInsensitive]) // 원본값 변경 X
ss // "Hello, hi"
str // "Hello, Swift"
Removing SubStrings
.removeSubrange() 메서드로 범위를 삭제할 수 있다.
.removeAll() 메서드로 문자열에서 모든 문자열을 삭제하고 빈 문자열을 만들어주며 파라미터 없이 호출하면 메모리 공간에서도 같이 삭제한다.
.removeAll(keepingCapacity: true) 이렇게 전달하면 메모리 공간은 삭제하지 않는다.
// 마지막 문자열 삭제하기
var str = "Hello, Swift!!!"
let a = str.index(before: str.endIndex)
var removed = str.remove(at: a) // 원본 변경 O
str // "Hello, Swift!!"
// 첫번째 문자열 삭제하기
removed = str.removeFirst()
removed // "H"
str // "ello, Swift!!"
// 마지막 문자열 삭제하기
removed = str.removeLast()
removed // "!"
str // "ello, Swift!"
// 문자열 앞에서 2개 삭제하기
str.removeFirst(2) // "lo, Swift!"
// 문자열 뒤에서 2개 삭제하기
str.removeLast(2) // "lo, Swif"
// 범위 지정하여 문자열 삭제하기
var str1 = "Hello, Swift!!!"
if let deleteStr = str1.range(of: "Swift") {
str1.removeSubrange(deleteStr)
str1 // "Hello, !!!"
}
String Comparison
문자열은 대소문자를 구분하여 비교할 수 있다.
var small = "apple"
var large = "Apple"
// 대소문자 비교하기
small == large // false
small != large // true
small < large // false
small > large // true
// 대소문자 구분 안하고 비교하기 (.caseInsensitive) *아래 두 코드 결과값 동일*
small.compare(large, options: [.caseInsensitive]) == .orderedSame // true
small.caseInsensitiveCompare(large) == .orderedSame
// 접두어 접미어 비교하기
let str = "hello, hi, 안녕?"
let prefix = "hello"
let suffix = "안녕?"
str.hasPrefix(prefix) // true
str.hasSuffix(suffix) // true
String Searching
문자열에서 단어, 범위, 공통 접두어를 검색할 수 있다.
Finding SubStrings
let str = "Hello, Swift"
// 단어 검색하기 .lowercased() 소문자로 변환해서 검색
str.lowercased().contains("hello") // true
// 범위지정해서 검색
str.range(of: "Swift") // "hello, hi"
str.range(of: "swift", options: [.caseInsensitive]) // "hello, hi"
// 공통 접두어 검색
let str2 = "Hello, hi"
let str3 = str2.lowercased()
var common = str.commonPrefix(with: str2)
//str 문자열 기준이기 때문에 "Hello, " 출력
common = str.commonPrefix(with: str3, options: [.caseInsensitive])
//str3 문자열 기준이기 때문에 "hello, " 출력
common = str3.commonPrefix(with: str, options: [.caseInsensitive])
Character Set
문자 집합으로, 문자열 검색이나 잘못된 문자열을 삭제할 때 주로 사용한다.
Character Set은 구조체로 값을 변경하려면 변수로 선언해야 한다.
복사해서 편집하는것도 가능하며 원하는 문자만으로 구성된 Character Set을 직접 만드는 것도 가능하다.
CharacterSet.uppercaseLetters
대문자만 포함된 CharacterSet이다.
let str = "hellO, swfiT"
var charSet = CharacterSet.uppercaseLetters
if let range = str.rangeOfCharacter(from: charSet) {
print(str.distance(from: str.startIndex, to: range.lowerBound )) // 4 (대문자 O)
}
if let range = str.rangeOfCharacter(from: charSet , options: [.backwards]) {
print(str.distance(from: str.startIndex, to: range.lowerBound )) // 11 (대문자 T)
}
CharacterSet.whitespaces
공백과 Tap 등이 포함된 CharacterSet이다.
.trimmingCharacters 메서드는 파라미터로 전달된 CharacterSet에 포함되어 있는 문자열을 삭제해주는 메서드이다.
let str = " S w i f t "
var charSet = CharacterSet.whitespaces
let trimmed = str.trimmingCharacters(in: charSet) // "S w i f t"
// 시작과 끝의 공백만 삭제해주고 나머지 공백은 삭제하지 않는다.
CharacterSet(charactersln:)
직접 CharacterSet을 사용할 수도 있다. (CustomCharacterSet)
//charactersIn: "@." 에 포함된 문자열을 분할하여 배열로 만들어준다.
let customCharSet = CharacterSet(charactersIn: "@.")
let emamil = "asdasd@gmail.Com"
let components = emamil.components(separatedBy: customCharSet) // ["asdasd", "gmail", "Com"]
'Swift > Swift문법' 카테고리의 다른 글
| Swift문법 - Collection (0) | 2023.02.26 |
|---|---|
| Swift문법 - String Options (0) | 2023.02.19 |
| Swift문법 - Tuples (0) | 2023.02.05 |
| Swift문법 - Closure (0) | 2023.01.28 |
| Swift문법 - Functions (0) | 2023.01.22 |