-
Swift - String CompareOptions (1)Programming/Swift 2021. 8. 4. 15:47
오늘은 이전에 사용하던 options 파라미터의 타입인 CompareOptions에 대해서 공부하도록 하겠습니다.
compare(_:options:) 메서드에서 options 파라미터를 보면 String.CompareOptions 타입으로 선언되어 있습니다.
String.CompareOptions는 NSString.CompareOptions 의 typealias입니다. (typealias에 대한 설명은 이전 포스팅을 참고해주세요.)
그럼 NSString.CompareOptions를 한번 찾아보겠습니다.
이름에 Compare만 들어갔다고 Comparing에만 사용되는 타입이 아닙니다.
Searching, Comparing, Sorting에 사용됩니다.
생각해보면 compare(_:options:) 메서드에서도 사용했고 range(of:options:)에서도 사용했습니다.
비교와 검색에서 사용을 한 것이죠.
지금까지 예시에서는 caseInsensitive만 사용했습니다. 하지만 options에는 많은 종류가 있습니다.
무엇이 있는지 한 번 보도록 하겠습니다.
상당히 많은 option이 있죠?
Option은 타입 프로퍼티로 선언이 되어있습니다.
그래서 사용을 할 때 인스턴스를 생성하는 게 아닌 타입명을 이용해서 사용합니다. (이 말이 이해가 안 된다면 이후에 포스팅할 Struct 포스팅을 참고해주세요.)
지금까지 예제에서는 앞에 타입명을 생략했는데 사실 정확한 문법은 앞에 타입명을 모두 적어야 합니다.
하지만 Swift에서는 추론이 가능하다면 생략이 가능합니다.
Line 4와 6은 똑같은 코드입니다. 하지만 line 6이 훨씬 보기 좋죠??
이번 포스팅에서는 모두 생략을 이용하여 작성하겠습니다.
그럼 options의 종류를 하나씩 자세히 보겠습니다.
caseInsensitive
caseInsensivite는 대, 소문자를 무시하고 비교합니다.
"BeePeach"와 "beePeach"는 Swift에서 다르게 인식합니다.
기준은 ASCII Code이므로 소문자 b가 대문자 B보다 큽니다.
결과를 보면 lowerPeach가 upperPeach보다 큰 것을 확인할 수 있습니다.
하지만 caseInsensitive options을 사용하면 대소문자를 무시하고 비교하므로 서로 같은 문자열로 판단합니다.
literal
literal은 문자의 동일성을 정확하게 비교하는 option입니다.
한글은 유니코드에 완성형과 조합형으로 나뉘어 할당되어 있습니다.
literal옵션을 사용하면 문자를 정확하게 비교하여 완성형과 조합형을 다른 문자로 판단합니다.
완성형은 글자가 완성되어 저장된 것으로 예시와 같이 "벌" 자체가 저장되어 있습니다.
반면 조합형은 한글을 초성, 중성, 종성으로 나누어 저장한 것으로 "ㅂ", "ㅓ", "ㄹ"을 조합하여 "벌"을 만듭니다.
bee와 b_e_e를 보면 코드가 다르죠?? 하지만 출력을 해보면 우리에게는 똑같은 "벌"로 보입니다.
그럼 이 둘을 비교하면 같을까요 다를까요??
Swift에서는 우리에게 보이는 최종 문자를 기준으로 비교를 합니다.
우리에게 보이는 문자는 모두 "벌"이므로 결과는 true가 나온 것을 확인할 수 있습니다.
반면 Objective-C는 최종 문자가 기준이 아니라 코드가 기준입니다.
만약 이 코드를 Objective-C에서 실행한다면 결과는 false입니다.
하지만 우리는 Swift를 주로 사용하니 이렇구나 간단히만 기억해주시면 됩니다.
options 파라미터에 literal을 보냈더니 결과는 false입니다.
둘 다 같은 "벌"이지만 문자를 정확하게 비교하여 완성형과 조합형은 다르다고 판단한 것입니다.
backwards
단어가 시작하는 부분을 왼쪽 끝나는 부분을 오른쪽 ( -> )으로 생각하실 수 있지만 이 기준은 우리가 기준을 한국어, 영어로 생각해서 그렇습니다.
아랍어는 우리와 반대로 오른쪽에서 시작해서 왼쪽으로 끝납니다. ( <- )
(예를 들어 우리는 '안녕? 비피치"라고 쓰지만 아랍어는 "치피비 ?녕안" 이런 식인겁니다.)
그래서 Swift에서는 left right 하지 않고 시작하는 부분을 leading 끝나는 부분을 trailing이라고 합니다.
backward는 문자열의 trailing부분부터 검색을 하는 option입니다.
코드를 보시면 "e"의 범위를 검색해서 범위의 rowbound로 index를 알아내는 코드입니다.
"BeePeach"에서 'e'는 3개 있습니다.
range(of:) 메서드는 leading 방향에서 첫 번째로 일치하는 문자열의 범위를 리턴해줍니다.
영어와 한국어는 -> 방향이기 때문에 B'e'epeach가 검색되었습니다.
그럼 여기서 options에 backward를 전달하면 trailing부분부터 검색을 하게 됩니다.
그럼 Beep'e'ach가 검색됩니다.
인덱스를 확인해보면 1과 4인 것을 확인할 수 있습니다.
anchored
anchored option은 prefix suffix를 생각하면 이해하기 쉽습니다.
anchored는 검색을 할 때 앞의 prefix부분만 하게 됩니다.
코드를 확인해보면 당연히 "BeePeach"는 "Hi, BeePeach"에 있기 때문에 옵셔널 바인딩이 성공하고 Found가 출력됩니다.
하지만 options에 anchored를 전달했더니 바인딩에 실패하고 NotFound가 출력되는 것을 확인할 수 있습니다.
검색을 접두어 부분인 "Hi"까지만 하기 때문에 "BeePeach"를 못 찾아서 nil을 리턴하게 되고 바인딩에 실패한 것입니다.
options는 이름과 같이 option을 여러 개 전달할 수 있습니다.
options으로 anchored와 backwards를 전달하면 어떻게 될까요??
그럼 suffix와 같아집니다.
"Hi BeePeach"의 뒷부분인 "BeePeach"에서 검색을 하게 되고 존재하기 때문에 Found가 출력되는 것을 확인할 수 있습니다.
아직 5가지 option이 더 남았습니다.
다음 포스팅에서 나머지 option을 다루도록 하겠습니다!
참고자료
https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html
728x90'Programming > Swift' 카테고리의 다른 글
Swift - CharacterSet (1) 2021.08.07 Swift - String CompareOptions (2) (0) 2021.08.05 Swift - String Search (문자열 검색) (0) 2021.08.03 Swift - Compare String (String 비교하기) (0) 2021.08.02 Swift - String Method, Property (Delete) (0) 2021.08.01