-
Swift - CharacterSetProgramming/Swift 2021. 8. 7. 21:30
오늘 공부해볼 주제는 CharacterSet입니다.
CharacterSet을 이용한 메서드에서 유용한 메서드가 있으므로 String을 공부하면서 같이 공부해보도록 하겠습니다.
CharacterSet
CharacterSet은 검색에서 사용하는 Unicode character의 Set입니다.
쉽게 말해서 Character들의 모임입니다.
그리고 이 CharacterSet을 파라미터로 전달해서 문자열을 검색하고 수정할 수 있습니다.
CharacterSet을 사용하기 위해서는 먼저 생성할 줄 알아야겠죠??
먼저 Swift에서 기본적으로 제공해주는 CharacterSet이 존재합니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters/// Returns a character set containing the characters in Unicode General Category Cc and Cf. public static var controlCharacters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category Zs and `CHARACTER TABULATION (U+0009)`. public static var whitespaces: CharacterSet { get } /// Returns a character set containing characters in Unicode General Category Z*, `U+000A ~ U+000D`, and `U+0085`. public static var whitespacesAndNewlines: CharacterSet { get } /// Returns a character set containing the characters in the category of Decimal Numbers. public static var decimalDigits: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category L* & M*. public static var letters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category Ll. public static var lowercaseLetters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category Lu and Lt. public static var uppercaseLetters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category M*. public static var nonBaseCharacters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Categories L*, M*, and N*. public static var alphanumerics: CharacterSet { get } /// Returns a character set containing individual Unicode characters that can also be represented as composed character sequences (such as for letters with accents), by the definition of "standard decomposition" in version 3.2 of the Unicode character encoding standard. public static var decomposables: CharacterSet { get } /// Returns a character set containing values in the category of Non-Characters or that have not yet been defined in version 3.2 of the Unicode standard. public static var illegalCharacters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category P*. public static var punctuationCharacters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category Lt. public static var capitalizedLetters: CharacterSet { get } /// Returns a character set containing the characters in Unicode General Category S*. public static var symbols: CharacterSet { get } /// Returns a character set containing the newline characters (`U+000A ~ U+000D`, `U+0085`, `U+2028`, and `U+2029`). public static var newlines: CharacterSet { get } 종류가 생각보다 많습니다.
대부분 이름을 보면 유추할 수 있는 CharacterSet입니다.
그럼 바로 코드를 작성해 보겠습니다.
문자열에서 대문자가 있는지 그리고 첫 번째 대문자의 인덱스가 어디인지 구하고 싶습니다.
기존에 우리가 사용하던 방법으로는 구하기 힘들겠죠???
이때 사용하는 메서드가 rangeOfCharacter(from:) 입니다.
rangeOfCharacter(from:options:range)
range(of:) 메서드와 차이점은 파라미터로 CharacaterSet을 받습니다.
CharacterSet.uppercaseLetters는 대문자 문자의 집합입니다.
그래서 문자열에 대문자가 있다면 범위를 리턴해주고 없다면 nil을 리턴해줍니다.
options도 파라미터로 받습니다.
그래서 우리가 이전에 공부한 String.CompareOptions도 사용할 수 있습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characterslet upperCharSet: CharacterSet = CharacterSet.uppercaseLetters let beepeach: String = "heLLo, beePeach" let startIndex: String.Index = beepeach.startIndex if let range: Range<String.Index> = beepeach.rangeOfCharacter(from: upperCharSet) { print(beepeach.distance(from: startIndex, to: range.lowerBound)) // 2 } if let range: Range<String.Index> = beepeach.rangeOfCharacter(from: upperCharSet, options: .backwards) { print(beepeach.distance(from: startIndex, to: range.lowerBound)) // 10 } Leading방향에서 첫 번째 대문자는 "L"로 2번째 index에 있습니다.
그리고 .backwards option을 사용하면 trailing부터 검색을 해서 "P"로 10번째 index에 있는 것을 확인할 수 있습니다.
init() 생성자로 빈 CharacterSet 만들기
기본으로 제공해주는 CharacterSet 말고 우리가 직접 만들 수도 있습니다.
(생성자에 대해서는 이후 생성자 포스팅에서 자세히 다루도록 하겠습니다.)
가장 기본적인 생성자는 빈 CharacterSet을 만드는 init() 생성자입니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersvar emptyCharSet: CharacterSet = CharacterSet() emptyCharSet.isEmpty // true CharacterSet()을 이용해서 빈 CharacterSet를 만들었습니다.
isEmpty 속성으로 CharacterSet이 비어있는지 아닌지 확인할 수 있습니다.
처음 생성하면 빈 CharacterSet입니다.
이 상태로는 사용하는 의미가 없으니 값을 추가시켜보겠습니다.
이 메서드를 이용하면 값을 추가시킬 수 있습니다.
파라미터로 String을 전달하면 CharacterSet에 추가됩니다.
코드를 보겠습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersemptyCharSet.insert("@") emptyCharSet.contains("@") // true emptyCharSet.isEmpty // false 빈 CharacterSet에 "@"를 추가시켰습니다.
그럼 더 이상 빈 CharacterSet이 아닌 것을 확인할 수 있습니다.
어떤 문자가 있는지 확인해보려면 contains(_:) 메서드를 이용합니다.
만약 파라미터로 전달한 문자가 CharacterSet에 존재한다면 true를 리턴해줍니다.
추가가 있으면 삭제도 있겠죠??
삭제는 remove(charactersIn:) 메서드를 이용합니다.
insert(characatersIn:)과 형식이 비슷하죠??
바로 예제를 보도록 하겠습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersemptyCharSet.remove(charactersIn: "@") emptyCharSet.isEmpty // true 이전에 추가시킨 "@"를 remove 했더니 다시 빈 CharacterSet이 된 것을 확인할 수 있습니다.
여기서 한 가지 의문이 들 수 있습니다.
CharacterSet 즉 Character의 집합인데 왜 파라미터로 String을 전달할까???
String으로 전달하면 String 포함된 Character 하나하나를 추가시키는 것과 같습니다.
예를 들어 "Swift"를 전달하면 S, w, i, f, t가 추가되는 셈입니다.
한번 확인해 보겠습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersemptyCharSet.insert(charactersIn: "@.") emptyCharSet.contains("@") // true emptyCharSet.contains(".") // true emptyCharSet.remove(charactersIn: "@.") emptyCharSet.isEmpty // true 파라미터로 "@." String을 전달했습니다.
만약 String이 저장됐다면 "@." 이 포함되어 있어야 하고 Character라면 "@", "."이 포함되어 있겠죠??
확인해보면 "@"와 "."이 저장되어 있습니다.
삭제할 때도 String을 전달하면 포함된 Character들을 모두 삭제시킵니다.
init(charactersIn:)
매번 CharacterSet을 생성할 때 빈 CharacterSet을 만들고 insert하면 조금 귀찮겠죠??
처음부터 생성할때 원하는 Set을 만들 수 있습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characterslet customCharSet: CharacterSet = CharacterSet(charactersIn: "@.") customCharSet.contains("@") // true customCharSet.contains(".") // true 코드를 보면 이전 코드보다 간결하게 CharacterSet을 생성할 수 있습니다.
그럼 마지막으로 유용한 메서드들을 보겠습니다.
components(separatedBy:)
이 메서드는 String을 주어진 CharacterSet을 기준으로 분리해서 배열에 담아 리턴해주는 메서드입니다.
만약에 String이 separator character로 시작하거나 끝난다면 배열의 시작과 끝은 빈 문자열로 채워집니다.
이전에 만든 customCharSet으로 email을 분리해보겠습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characterslet customCharSet: CharacterSet = CharacterSet(charactersIn: "@.") var email: String = "beepeach@gmail.com" var components: [String] = email.components(separatedBy: customCharSet) print(components) // ["beepeach", "gmail", "com"] email = "@beepeach@gmail.com." components = email.components(separatedBy: customCharSet) print(components) // ["", "beepeach", "gmail", "com", ""] CharacterSet과 메서드를 이용하면 분리할 문자가 다른 경우도 이렇게 쉽게 나눌 수 있습니다.
trimmingCharacters(in:)
이 메서드는 String의 양끝이 주어진 CharacterSet을 포함한다면 양 끝을 삭제한 문자열을 리턴해주는 메서드입니다.
주로 문자열을 입력받을 때 원치 않게 좌우에 공백이 들어간 경우 이를 제거할 때 자주 사용합니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characterslet email: String = "b e e peach@gmail.com " let charSet: CharacterSet = .whitespaces let trimmedEmail: String = email.trimmingCharacters(in: charSet) print(trimmedEmail) // b e e peach@gmail.com let correctEmail: String = email.replacingOccurrences(of: " ", with: "") print(correctEmail) // beepeach@gmail.com 코드를 잘 보시면 email 중간과 마지막에 공백이 추가되어 있습니다.
이 문자열을 trimming 시키면 좌우 공백은 사라졌지만 문자열 내부에 있는 공백은 사라지지 않았습니다.
이를 해결하려면 우리가 이전에 공부했던 replacingOccurrences(of:with:)를 이용하여 공백은 빈 문자열로 바꿔주면 해결할 수 있습니다.
참고자료
여러분의 새로운 도전을 응원합니다 | KxCoding
Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기
kxcoding.com
https://developer.apple.com/documentation/foundation/characterset
Apple Developer Documentation
developer.apple.com
728x90'Programming > Swift' 카테고리의 다른 글
Swift - Foundation Collection & Swift Collection (0) 2021.08.28 Swift - Sequence와 Collection (Sequence와 Collection의 차이) (2) 2021.08.11 Swift - String CompareOptions (2) (0) 2021.08.05 Swift - String CompareOptions (1) (0) 2021.08.04 Swift - String Search (문자열 검색) (0) 2021.08.03