티스토리 뷰
6. String Basics
기본적인 문자열의 특징 및 표현 방식 등에 대해 알아보겠습니다.
// 문자열 리터럴을 이용
var str = "Hello, Swift String"
// 빈 문자열 저장
var emptyStr = ""
emptyStr = String()
let a = String(true) // 결과: "true"
let b = String(12) // 결과: "12"
let c = String(12.34) // 결과: "12.34"
let d = String(str) // 결과: "Hello, Swift String"
// 123 을 16, 8, 2진수 문자열로 생성
let hex = String(123, radix: 16) // 결과: "7b"
let octal = String(123, radix: 8) // 결과: "173"
let binary = String(123, radix: 2) // 결과: "1111011"
// 문자 반복해서 출력하기
let repeatStr = String(repeating: "👏🏻", count: 7)
let unicode = "\u{1f44f}"
// 문자열 합치기
let e = "\(a) \(b)" // 결과: "true 12"
let f = a + " " + b // 결과: "true 12"
str += "!!" // 결과: "Hello, Swift String!!"
// 문자열의 길이를 반환
str.count // 결과: 21
// 빈 문자열인지 확인하여 boolean 값 반환
str.isEmpty // 결과: false
// 문자열 비교 시 대소문자 구분
"apple" == "Apple" // 결과: false
"apple" != "Apple" // 결과: true
// 사전 순 문자 비교 (같은 문자인 경우 ASCII 값 비교)
"apple" < "Apple" // 결과: false
// ed(), ing() 로 끝나는 메소드는 원래 값은 그대로 두고 새로운 값을 리턴
str.lowercased() // 결과: hello, swift string!!
str.uppercased() // 결과: HELLO, SWIFT STRING!!
str // 결과: Hello, Swift String!!
// 각 단어의 처음 문자를 대문자로 변경
str.capitalized // 결과: Hello, Swift String
"apple ipad".capitalized // 결과: Apple Ipad
// 문자열은 Characters Sequence
for char in "Hello" {
print(char)
}
// 결과
H
e
l
l
o
let num = "1234567890"
// 문자열의 문자 중 아무 숫자나 하나 뽑기
num.randomElement()
// 문자열의 문자를 랜덤으로 섞어서 문자 배열로 리턴
num.shuffled() // 결과: ["5", "6", "9", "2", "1", "7", "0", "3", "8", "4"]
7. Substring
Substring 타입은 원본 문자열과 메모리 공간을 공유하여 메모리 낭비를 방지하는 장점을 가지고 있습니다. Substring 타입의 변수 값을 변경하는 시점에 새로운 문자열을 생성하기 때문에 원본 문자열에 영향을 주지 않고 값을 바꿀 수 있습니다. 이런 방식을 Swift 에서는
Copy-on-Write Optimization(불필요한 복사와 메모리 생성을 최대한 줄여 실행 성능을 높임) 이라고 합니다.
let str = "Hello, Swift"
let l = str.lowercased()
// first 는 String.Subsequence (= Substring) 타입으로
// 새로운 문자열이 아닌 기존 str 문자열의 저장 공간을 공유
var first = str.prefix(1)
// insert 메소드를 통해 값을 변경하고 있기 때문에
// 이때, 새로운 문자열로 생성
first.insert("!", at: first.endIndex)
str // 결과: Hello, Swift
first // 결과: H!
// 바로 새로운 문자열로 저장하는 방법
let newStr = String(str.prefix(1))
// 문자열을 원하는 만큼 잘라내는 방법
// 이제 substring 메소드를 사용하지 않음
// str.substring(to: str.index(str.startIndex, offsetBy: 2))
let s = str[str.startIndex ..< str.index(str.startIndex, offsetBy: 2)] // 결과: "He"
// 위와 같음
// let s = str[..<str.index(str.startIndex, offsetBy: 2)]
str[str.index(str.startIndex, offsetBy: 2)...] // 결과: "llo, Swift"
let lower = str.index(str.startIndex, offsetBy: 2)
let upper = str.index(str.startIndex, offsetBy: 5)
str[lower ... upper] // 결과: "llo,"
8. String Editing
문자열을 변경하는 방법에 대해 알아보겠습니다.
// Appending Strings and Characters
// 문자열 뒤에 새로운 문자열 추가
var str = "Hello"
str.append(", ") // 값을 리턴하지 않음 (대상 문자열을 직접 변경)
str // 결과: "Hello,"
// 대상 문자열을 직접 변경하지 않고 새로운 값을 리턴
let s = str.appending("Swift")
str // 결과: "Hello,"
s // 결과: "Hello, Swift"
"File size is ".appendingFormat("%.1f", 12.3456) // 결과: "File size is 12.3"
// 문자열 중간에 문자열 추가
var str2 = "Hello Swift"
str2.insert(",", at: str.index(str.startIndex, offsetBy: 5))
if let sIndex = str2.firstIndex(of: "S") {
str2.insert(contentsOf: "Awesome ", at: sIndex)
}
str2 // 결과: "Hello, Awesome Swift"
// Replacing Substrings
var str3 = "Hello, Objective-C"
if let range = str3.range(of: "Objective-C") {
str3.replaceSubrange(range, with: "Swift")
}
str3 // 결과: "Hello, Swift"
if let range2 = str3.range(of: "Hello") {
let s = str3.replacingCharacters(in: range2, with: "Hi")
s // 결과: "Hi, Swift"
str3 // 결과: "Hello, Swift"
}
var ss = str3.replacingOccurrences(of: "Swift", with: "Awesome Swift")
ss // 결과: "Hello, Awesome Swift"
// 대소문자 비교 없이 값을 찾아 변경
ss = str3.replacingOccurrences(of: "swift", with: "Awesome Swift", options: [.caseInsensitive])
// 결과: "Hello, Awesome Swift"
// Removing Substrings
var str4 = "Hello, Awesome Swift!!!"
let lastCharIndex = str4.index(before: str4.endIndex)
var removed = str4.remove(at: lastCharIndex)
removed // 결과: "!"
str4 // 결과: "Hello, Awesome Swift!!"
removed = str4.removeFirst()
removed // 결과: "H"
str4 // 결과: "ello, Awesome Swift!!"
// removeFirst 에 파라미터가 있는 경우 값을 반환하지는 않음
str4.removeFirst(2)
str4 // 결과: "lo, Awesome Swift!!"
str4.removeLast() // 결과: "!"
str4 // 결과: "lo, Awesome Swift!"
// removeLast 도 마찬가지로 파라미터가 있는 경우 값을 반환하지 않음
str4.removeLast(2)
str4 // 결과: "lo, Awesome Swif"
if let range = str.range(of: "awesome") {
str4.removeSubrange(range)
str4
}
// 메모리 공간도 같이 삭제
str4.removeAll()
// 메모리 공간을 유지(값을 지우고 다른 값을 저장할 때 사용)
str4.removeAll(keepingCapacity: true)
str4 = "Hello, Awesome Swift!!!"
// 원본 문자열에서 마지막 문자를 제외한 나머지를 공유하게 됨
var substr = str4.dropLast()
substr = str4.dropLast(3)
// 문자열을 돌면서 문자가 , 일때 return
substr = str4.drop(while: { (ch) -> Bool in
return ch != ","
})
substr // 결과: ", Awesome Swift!!!"
9. String Comparision
문자열 비교에 대해 알아보겠습니다.
let largeA = "Apple"
let smallA = "apple"
let b = "Banana"
// Swift 는 기본적으로 대소문자를 구분하여 비교
largeA == smallA // 결과: false
largeA != smallA // 결과: true
largeA < smallA // 결과: true
largeA < b // 결과: true
smallA < b // 결과: false => ASCII 코드 상 소문자 a 가 B 보다 큼
largeA.compare(smallA) == .orderedSame // 결과: false
// 대소문자 구분 없이 비교하고 싶다면
largeA.caseInsensitiveCompare(smallA) == .orderedSame // 결과: true
largeA.compare(smallA, options: [.caseInsensitive]) == .orderedSame // 결과: true
let str = "Hello, Swift Programming!"
var prefix = "Hello"
let suffix = "Programming"
str.hasPrefix(prefix) // 결과: true
str.hasSuffix(suffix) // 결과: false => 문자열을 뒤에서부터 비교해서 같은지 확인
prefix = "hello"
// 대소문자 구분 없이 비교하려면
str.lowercased().hasPrefix(prefix.lowercased()) // 결과: true
10. String Searching
문자열 내부 검색 방법을 알아보겠습니다.
let str = "Hello, Swift"
// 대소문자 구분해서 검색
str.contains("Swift") // 결과: true
str.contains("swift") // 결과: false
str.lowercased().contains("swift") // 결과: true
// 범위 검색
str.range(of: "Swift")
// 대소문자 구분 없이 범위 검색
str.range(of: "swift", options: [.caseInsensitive])
let str2 = "Hello, Programming"
let str3 = str2.lowercased()
// 접두어 검색
// 공통적인 접두어만 새로운 문자열로 리턴
var common = str.commonPrefix(with: str2) // 결과: "Hello, "
common = str.commonPrefix(with: str3) // 결과: ""
str.commonPrefix(with: str3, options: [.caseInsensitive]) // 결과: "Hello, "
str3.commonPrefix(with: str, options: [.caseInsensitive]) // 결과: "hello, "
11. String Options
문자열 옵션 9가지에 대해 알아보겠습니다.
// 1. Case Insensitive Option
"A" == "a"
"A".caseInsensitiveCompare("a") == .orderedSame
"A".compare("a", options: [.caseInsensitive]) == .orderedSame // 결과: true
// .caseInsensitive == NSString.CompareOptions.caseInsensitive
// 2. Literal Option
// 코드 유닛이 달라도 최종 문자가 같다면 같은 문자로 인식
// 코드 유닛에 따라 문자를 비교하고 싶을 때 사용
let a = "\u{D55C}"
let b = "\u{1112}\u{1161}\u{11AB}"
a == b
a.compare(b) == .orderedSame
// literal option 을 사용하는 것이 더 빠름
a.compare(b, options: [.literal]) == .orderedSame // 결과: true
// 3. Backwards Option
// 검색 방향을 지정하는 옵션
let korean = "행복하세요"
let english = "Be happy"
let arabic = "كن سعيدا"
if let range = english.range(of: "p") {
english.distance(from: english.startIndex, to: range.lowerBound) // 결과: 5
}
if let range = english.range(of: "p", options: [.backwards]) {
english.distance(from: english.startIndex, to: range.lowerBound) // 결과: 6
}
// 4. Anchored Option
// 검색 범위를 문자열의 시작이나 끝으로 제한
let str = "Swift Programming"
if let result = str.range(of: "Swift") {
print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
print("no found")
}
if let result = str.range(of: "Swift", options: [.backwards]) {
print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
print("no found")
}
// 시작 부분만 검색
if let result = str.range(of: "Swift", options: [.anchored]) {
print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
print("no found")
}
// 마지막 부분만 검색
if let result = str.range(of: "Swift", options: [.anchored, .backwards]) {
print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
print("not found")
}
// 결과
0
0
0
not found
str.lowercased().hasPrefix("swift")
// 위와 같은 코드
if let _ = str.range(of: "swift", options: [.anchored, .caseInsensitive]) {
print("same prefix")
}
str.lowercased().hasSuffix("swift")
// 위와 같은 코드
if let _ = str.range(of: "swift", options: [.anchored, .backwards, .caseInsensitive]) {
print("same suffix")
}
// 5. Numeric Option
// 문자에 할당된 코드의 크기를 비교
"A" < "B"
"a" < "B"
let file9 = "file9.txt"
let file10 = "file10.txt"
file9 < file10
file9.compare(file10) == .orderedAscending
// 문자열에 포함된 숫자를 숫자 자체로 비교
file9.compare(file10, options: [.numeric]) == .orderedAscending // 결과: true
// 6. Diacrtic Insensitive
// 발음 기호를 처리하는 옵션
let aa = "Cafe"
let bb = "Cafè"
aa == bb
aa.compare(bb) == .orderedSame
// 발음 기호를 무시하고 문자를 비교할 때
aa.compare(bb, options: [.diacriticInsensitive]) == .orderedSame // 결과: true
// 7. Width Insensitive Option
// 전각, 반각 문자의 크기가 다른 경우 같은 문자라도 다르게 인식하기 때문에
// 이를 같게 비교하기 위해 사용
let aaa = "\u{30A1}" // 전각 문자
let bbb = "\u{ff67}" // 반각 문자
aaa == bbb
aaa.compare(bbb) == .orderedSame
aaa.compare(bbb, options: [.widthInsensitive]) // 결과: true
// 8. Forced Ordering Option
// 강제 정렬 옵션
// 전체 옵션을 적용했을 때 같은 문자열로 판단된다면
// 일부 옵션을 무시하고 최대한 문자열의 순서를 파악할 수 있는 값을 리턴
let upper = "STRING"
let lower = "string"
upper == lower
upper.compare(lower, options: [.caseInsensitive]) == .orderedSame
upper.compare(lower, options: [.caseInsensitive, .forcedOrdering]) == .orderedSame // 결과: false
// 9. Regular Expression
// 정규식 파악 옵션
let emailPattern = "([0-9a-zA-Z_-]+)@([0-9a-zA-Z_-]+)(\\.[0-9a-zA-Z_-]+){1,2}"
let emailAddress = "user@example.com"
// 그냥 range(of:)를 사용하면 문자열 자체를 포함하고 있는지를 비교
if let _ = emailAddress.range(of: emailPattern) {
print("found")
} else {
print("not found")
}
if let range = emailAddress.range(of: emailPattern, options: [.regularExpression])
, (range.lowerBound, range.upperBound) == (emailAddress.startIndex, emailAddress.endIndex) {
print("found")
} else {
print("not found")
}
// 결과
not found
found
12. Character Set
문자열 모음에 대해 알아보겠습니다.
// 대문자가 포함된 문자열 모음
let a = CharacterSet.uppercaseLetters
// 대문자를 제외한 문자열 모음
let b = a.inverted
// 검색 코드 구현
var str = "loRem Ipsum"
var charSet = CharacterSet.uppercaseLetters
if let range = str.rangeOfCharacter(from: charSet) {
print(str.distance(from: str.startIndex, to: range.lowerBound)) // 결과: 2
}
if let range = str.rangeOfCharacter(from: charSet, options: [.backwards]) {
print(str.distance(from: str.startIndex, to: range.lowerBound)) // 결과: 6
}
str = " A p p l e "
// 문자열 양쪽의 공백 제거
charSet = .whitespaces
let trimmed = str.trimmingCharacters(in: charSet)
print(trimmed) // 결과: "A p p l e"
// CharacterSet 편집
var editTarger = CharacterSet.uppercaseLetters
editTarger.insert("#") // 문자 하나 추가
editTarger.insert(charactersIn: "~!@") // 여러 개 문자 추가
editTarger.remove("A") // 문자 하나 삭제
editTarger.remove(charactersIn: "BCD") // 여러 개 문자 삭제
// Custom CharacterSet 만들기
let customCharSet = CharacterSet(charactersIn: "@.")
let email = "userId@example.com"
let component = email.components(separatedBy: customCharSet)
// 결과: ["userId", "example", "com"]
'swift > 문법' 카테고리의 다른 글
14. Swift 문법 - Collections 2 (Dictionary, Set) (0) | 2020.10.20 |
---|---|
13. Swift 문법 - Collections 1 (Array) (0) | 2020.10.20 |
11. Swift 문법 - Strings and Characters 1 (0) | 2020.10.19 |
10. Swift 문법 - Tuples (0) | 2020.10.17 |
09. Swift 함수 - Closures (0) | 2020.10.17 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- map
- 프로그래머스
- programmers
- 조합
- 에라토스테네스의 체
- cloudfront
- ECR
- 순열
- DFS
- sort
- BFS
- Baekjoon
- ionic
- java
- search
- 소수
- array
- CodeCommit
- CodePipeline
- Algorithm
- EC2
- permutation
- 수학
- Dynamic Programming
- string
- SWIFT
- spring
- AWS
- CodeDeploy
- Combination
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함