[Swift] 문자열 [2]

임승섭·2023년 7월 14일
1

Swift

목록 보기
33/35

문자열 다루기

문자열 <-> 배열

var someString = "Swift"

// ⭐️ 1. 문자열을 문자열 배열화 하기 (문자열에도 map이 구현되어 있다)
// $0는 character type으로 주기 때문에 String으로 바꿔준다
var array: [String] = someString.map { String($0) }		// ["S", "w", "i", "f", "t"]

// 2. 문자열을 문자 배열화 하기 (거의 쓰지 않는다)
// 배열 자체의 생성자 - 알아서 배열이 된다.
var array2: [Character] = Array(somerString)		// ["S", "w", "i", "f", "t"]
// array와 array2의 타입이 다르다는 것을 유의하자

// 1-1. 문자열을 문자열 배열화하는 추가적 방법
var array3: [String] = Array(arrayLiteral: someString)

/* 이제 반대로 */
// 3. 문자열 배열 -> 문자열
var newString = array.joined()	// 다시 문자열로 합쳐준다
newString = array3.joined()

// 4. 문자 배열 -> 문자열
// [character]에는 joined() 메서드가 없다
var newString2 = String(array2)

활용

someString = "Swift"

someString.randomElement()	// 문자열에서 랜덤으로 뽑아냄
someString.suffled()		// 섞어서 문자 배열([Character])로 리턴


// ⭐️ 문자열을 배열로 먼저 바꾸고(map), 뒤죽박죽 섞고(shuffled), 다시 문자열로 합쳐준다(joined)
newString3 = someString.map {String($0) }.shuffled().joined()

// shuffled()로 나온 문자 배열을 문자열로 만들어준다
newString4 = String(someString.shuffled())

문자열의 인덱스

  • 문자열의 인덱스는 정수가 아니다
    • 스위프트에서는 문자열을 글자의 의미단위로 사용하기 때문에, 정수 인덱스 사용 불가
  • 배열은 안에 들어가는 타입이 모두 같기 때문에, 각 원소의 메모리 사이즈가 같다.
    하지만, 문자열은 글자마다 메모리 상의 데이터 사이즈가 다르기 때문에, 일정하지 않은 간격으로 데이터가 존재한다
let greeting = "Guten Tag!"
greeting.startIndex
print(greeting.startIndex)		// Index(_rawBits: 15)
// 정수 형태의 인덱스가 아니다!!
greeting[greeting.startIndex]	// "G"



/* ⭐️ 정수 형태를 한 번 변형해서 사용한다 */
// startIndex부터 2만큼 떨어진 index를 뽑아낸다
var someIndex = greeting.index(greeting.startIndex, offsetBy: 2)	
greeting[someIndex]		// "t"

// startIndex의 다음 인덱스를 뽑아낸다
someIndex = greeting.index(after: greeting.startIndex)
greeting[someIndex]		// "u"

// endIndex의 직전 인덱스를 뽑아낸다
someIndex = greeting.index(before: greeting.endIndex)
greeting[someIndex]		// "!"

// for문으로 문자 하나씩 뽑아내는 방법
// 1.
for index in greeting.indices {       // 개별 문자의 인덱스에 접근
    print("\(greeting[index]) ", terminator: "")
}
print("")

// 2. 
for char in greeting {
    print("\(char) ", terminator: "")
}


/* 공백 문자열 다음의 글자를 출력해라 */
var firstIndex = greeting.firstIndex(of: " ")!		// 옵셔널
var nextOfEmptyIndex = greeting.index(firstIndex, offsetBy: 1)
greeting[nextOfEmptyIndex]


/* 세 번째 글자를 출력해라 */
var thirdCharIndex = greeting.index(greeting.startIndex, offsetBy: 2)
greeting[thirdCharIndex]



/* 문자열의 특정 범위를 추출한다 */
let lower = greeting.index(greeting.startIndex, offsetBy: 2)
let upper = greeting.index(greeting.startIndex, offsetBy: 5)
greeting[lower...upper]

var range = greeting.range(of: "Tag!")!		// 범위를 뽑아낸다
greeting[range]

range = greeting.range(of: "tag", options: [.caseInsensitive])!	// 대소문자 상관없이
greeting[range]

삽입, 교체, 추가, 삭제

/* 삽입 */
var welcome = "Hello"
welcome.insert("!", at: welcome.endIndex)	// Chracter 형태만 삽입, index는 정수x
// "Hello!"

welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
// "Hello there!"



/* 교체 */
welcome = "Hello there!"

if let range = welcome.range(of: "there!") {
	welcome.replaceSubrange(range, with: "Swift!")
}

// 교체하되, 원본은 그대로 하기
var newWelcome = welcome.replacingOccurrences(of: "Swift", with: "World")

newWelcome = welcome.replacingOccurrences(of: "swift", with: "New World", options: [.caseInsensitive], range: nil)		// 대소문자 무시 옵션



/* 추가 */
"swift" + "!"

welcome.append("~")
welcome.append(" Awesome!")




/* 삭제 */
welcome = "Hello Swift!"

// 인덱스로 삭제
welcome.remove(at: welcome.index(before: welcome.endIndex))

// 인덱스 범위 파악하고 삭제
var range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
// range = welcome.range(of: " Swift")!
welcome.removeSubrange(range)

// 전체 삭제
welcome.removeAll()
welcome.removeAll(keepingCapacity: true)

활용

var string = "Hello world"

// 1. 공백 문자열의 인덱스 찾기
// 2. 공백 문자열의 인ㄷ게스에 " super" 삽입하기
if let someIndex = string.firstIndex(of: " ") {
	string.insert(contentsOf: " super", at: someIndex)
}



// 1. 첫 공백 문자열의 인덱스 찾기
// 2. " super" 문자열의 범위 만들기
// 3. 범위 삭제하기
if let firstIndex = string.firstIndex(of: " ") {
    let range = firstIndex...string.index(firstIndex, offsetBy: 5)
    string.removeSubrange(range)
    print(string)     // "Hello world"
}



// 바꿀 문자열을 정확하게 알고 있다면 ===> 범위를 직접 리턴하는 메서드 활용 ⭐️
if let range = string.range(of: " world") {
    string.removeSubrange(range)
    print(string)
}

문자열 비교

단순 비교

// 비교연산자
"swift" == "Swift"		// false
"swift" != "Swift"		// true

// 크기 비교 (유니코드 비교)
"swift" < "Swift"		// false


// 대소문자 무시하고 비교하는 메서드
var a = "swift"
var b = "Swift"
var result = a.caseInsensitiveCompare(b)		// 결과값이 NSComparisonResult. bool 타입이 아니다!

/* ComparisonResult : 열거형 타입으로 정의되어있다.
1. orderedSame
2. orderedAscending
3. orderedDescending
단순히 같은지 틀린지 뿐만 아니라, 결과가 오름/내림차순인지 확인할 수 있다!! good
*/

switch result {
case .orderedAscending:
	print("오름차순")
case .orderedDescending:
	print("내림차순")
case .orderedSame:
	print("동일한 차순")
}

a.caseInsensitiveCompare(b) == ComparisonResult.orderedSame

문자열 비교 메서드

  • 다양한 옵션 적용이 가능해서 비교를 여러가지 방식으로 활용할 수 있다
var name = "Hello, Swift"

name.compare("hello", options: [.caseInsensitive]) == .orderedDescending	// true
// option을 넣어줄 때, 배열 형태로 넣어줄 수도 있고, 하나만 넣어줄 수도 있다.
// 이는 OptionSet 프로토콜을 채택한 애들에 한해서 가능하다
// 위와 마찬가지로, 이렇게 바로 비교해도 되고 switch 문을 이용해도 된다


/* 비교 옵션 */ 
/**==========================================
 [String.CompareOptions 구조체]와 내부의 타입 속성들
 - .caseInsensitive       // 대소문자 무시하고 ⭐️
 
 - .diacriticInsensitive  // 발음구별기호 무시하고
 - .widthInsensitive      // 글자 넓이 무시하고
 
 - .forcedOrdering        // 강제적 오름차순/내림차순 정렬순 (대소문자 무조건 구별 의미)
 - .literal               // (유니코드 자체로) 글자그대로
 	- ("한"과 "ㅎㅏㄴ"을 다른 글자로 인식한다)
 - .numeric               // 숫자 전체를 인식해서 비교
 	- (10이 9보다 뒤에 있게 해준다)
 
 - .anchored              // (앞부분부터) 고정시키고 (접두어)
 - .backwards             // 문자 뒷자리부터

 - .regularExpression     // 정규식 검증 ⭐️
=============================================**/

문자열 포함여부 및 앞뒤 글자 반환

let string = "Hello, world!"

// 전체문자열에서 포함여부
string.contains("Hello")
string.lowercased().contains("hello")
string.contains("world")

// 접두어/접미어 포함여부
string.hasPrefix("Hello")
string.hasPrefix("world")
string.lowercased().hasPrefix("world")
string.hasSuffix("!")
string.hasSuffix("world!")

// 접두어/접미어 반환 (앞에서 또는 뒤에서 몇글자 뽑아내기)
string.prefix(2)
string.suffix(3)

// 공통 접두어 반환
string.commonPrefix(with: "Hello, swift")
string.commonPrefix(with: "hello", options: [.caseInsensitive])

// 앞/뒤를 drop시킨 나머지 반환
string.dropFirst(3)
string.dropLast(3)

1개의 댓글

comment-user-thumbnail
2023년 12월 12일

잘봤습니다 감사합니다

답글 달기