swift

swift - Options

행복하게사는게꿈 2021. 1. 6. 22:51

Options

swift는 총 9개의 Options를 제공함

 

메소드에서 Options 파라미터를 갖는 메소드에서 사용가능


Case Insensitive Option

대소문자 상관없이 비교

// swift에서는 모두 9개의 문자열 옵션을 제공

// String 문자열 메소드에서 opions 파라미터를 가진 메소드에서 모두 사용 가능
"A" == "a"

// .caseInsensitiveCompare() 메소드는 Bool을 리턴하는게 아니라 comparisonResult를 리턴하기 때문에
// .orderedSame같은 것으로 비교해 주어야 함
// 둘은 같은 코드
"A".caseInsensitiveCompare("a") == .orderedSame
"A".compare("a", options: [.caseInsensitive]) == .orderedSame

// compare 메소드의 options: [.caseInsensitive] 는
// NSString.CompareOptions.caseInsensitive를 생략한 것인데 왜 생략할 수 있냐면? 형식을 추론할 수 있기 때문에

Literal Option

리터럴 단위로 비교

// "한" 완성형
let a = "\u{D55C}"

// "한" 조합형
let b = "\u{1112}\u{1161}\u{11AB}"

// 최종문자가 같으면 true를 반환한다.
a == b
a.compare(b) == .orderedSame

// literal Options 사용 하면 false
// object-c랑 동일한 비교방법임 literal 단위로 비교
a.compare(b, options: [.literal]) == .orderedSame


Backwards Option

문자열의 검색 방향을 바꾸는 옵션

let korean = "행복하세요"
let english = "Be happy"
let arabic = "كن سعيدا"

// 문자열 시작부분이 왼쪽이 될 수도 있고 오른쪽이 될 수도 있기때문에
// swift는 문자열 시작부분이 Leading, 끝부분이 Trailing이라고 표현

// leading부터 검색
if let range = english.range(of: "p") {
    english.distance(from: english.startIndex, to: range.lowerBound)
}

// trailing부터 검색
if let range = english.range(of: "p", options: [.backwards]) {
    english.distance(from: english.startIndex, to: range.lowerBound)
}

Anchored Option

검색 대상을 제한

// backwords options과 혼동하기 쉬움
// backwords options은 검색 방향을 바꾸는거지 검색 대상을 바꾸는게 아님

// 전체 문자열을 대상으로 검색

// 이건 전체 문자열을 대상으로 하지 않음
// 검색 부분을 문자열 시작 부분이나 마지막부분으로 제한

let str = "Swift programming"

if let result = str.range(of: "Swift") {
    print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
    print("not found")
}

// backwords options
if let result = str.range(of: "Swift", options: [.backwards]) {
    print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
    print("not found")
}

if let result = str.range(of: "Swift", options: [.anchored]) {
    print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
    print("not found")
}

if let result = str.range(of: "Swift", options: [.anchored, .backwards]) {
    print(str.distance(from: str.startIndex, to: result.lowerBound))
} else {
    print("not found")
}


str.hasPrefix("swift")
if let _ = str.range(of: "swift", options: [.anchored, .caseInsensitive]) {
    print("same prefix")
}

str.hasSuffix("swift")

Numberic Option

정확한 숫자 비교 옵션

// swift는 기본적으로 사전순으로 비교하지 않고 아스키 코드로 비교한다.
"A" < "B"
"a" < "B"

let file9 = "file9.txt"
let file10 = "file10.txt"

file9 < file10

file9.compare(file10) == .orderedAscending

// 9보다 10이 더 크지만 9랑 1이랑 비교되기 때문에 false

// 요롷게 해줘야 숫자끼리의 정상적인 비교가 된다.
file9.compare(file10, options: [.numeric]) == .orderedAscending
 

Diacritic Insensitive

발음 기호 무시하고 비교

// 발음기호 처리 option
// swift는 문자열 비교할때 우리 눈에 보이는 그대로를 비교
let a = "Cafe"
let b = "Cafè"

a == b
a.compare(b) == .orderedSame

// 발음기호 무시하고 문자 비교
a.compare(b, options: [.diacriticInsensitive]) == .orderedSame

Width Insensitive Option

반강문자 정강문자 비교?

// 아시아 국가에서 사용하는 문자들을 보면 정강문자와 반강문자로 표현할 수 있다.
// 반강문자는 정강문자의 절반의 넓이를 가짐

// 정강문자
let a = "\u{30A1}"

// 반강문자
let b = "\u{ff67}"

a == b // false
a.compare(b, options: [.widthInsensitive]) == .orderedSame // true

Forced Ordering Option

어떠한 경우에도 강제로 정렬

// 어떤 경우에도 강제로 정렬
let upper = "STRING"
let lower = "string"

upper == lower // false
upper.compare(lower, options: [.caseInsensitive]) == .orderedSame // true

// .forcedOrdering option은 전체옵션을 적용했을때 같은 문자열으로 판단된다면
// 일부 옵션을 무시하고 최대한 문자열의 순서를 파악할 수 있게 한다.
// 이 경우 caseInsenitive 옵션을 제외한다.
upper.compare(lower, options: [.caseInsensitive, .forcedOrdering]) == .orderedSame // false

Regular Expression

정규식으로 문자열 평가

// 주로 입력된 값을 검증할때 사용

let emailPattern = "([0-9a-zA-Z_-]+)@([0-9a-zA-Z_-]+)(\\.[0-9a-zA-Z_-]+){1,2}"
let emailAddress = "user@example.com😆"

// 이코드는 문자열 그대로를 비교하기 때문에 당연히 실패
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")
}