[Swift] Unicode property 로 한글 판별하기

\p{Hangul} 이 뭔데요?

naljin
10 min readMay 20, 2023

들어가기 전에

개-하! 한글이나 영어가 들어가있는지 판별하기 위해서 어떻게 작성할 것 같으신가여?

뭐 구글링을 하거나 챗지피티한테 물어보면 방법이야 다양하겠지만, 그 중 한가지 방법으로

extension String {
var isHangul: Bool {
return "\(self)".range(of: "\\p{Hangul}", options: .regularExpression) != nil
}

var isLatin: Bool {
return "\(self)".range(of: "\\p{Latin}", options: .regularExpression) != nil
}
}

이렇게도 할 수 있답니다요?

ㅎㅎ.. 그리고 이번 글은 “🤔 ???? p{Hangul} 저게 뭐임?” 이라고 생각하시는 분(aka. 나)들을 위한 글입니다!!

그럼 시작해보죠 ㄱㄱㄱ

p{Hangul} 이 뭔데?

아래의 코드를 한번 보고 Hangul 이 뭘지.. 유추해봅시다.

range(of: "\\p{Hangul}", options: .regularExpression)

🤔 음… 옵션에서 .regularExpression 이 들어가있네...? 그럼 p{Hangul} 은 정규 표현식과 관련된 값인가...?

두둥 맞습니다. NSRegularExpression 문서를 보면 정규식 메타 character (string 에서 character 를 일치시키는 데 사용되는 값) 를 찾아볼 수 있는데요!

그 중 \p{유니코드 프로퍼티 이름} 은 지정된 유니코드 속성을 가진 캐릭터와 일치 시킨다고 나와있습니다.

그렇다면 여기서 “🤔 유니코드 프로퍼티 이름에는 어떤 값들이 있는데??? 여기에 Hangul 이 포함되어 있는거겠지?" 라는 의문이 듭니다.

유니코드에는 정말 다양한 프로퍼티들이 있고, 각각의 프로퍼티는 특정 분류에 속해있습니다. 이해를 돕기 위해 예시를 들어보겠습니다.

유니코드의 분류 중에는 General_Category 가 있고, 이 안에 속하는 프로퍼티들을 통해 문자의 일반 범주를 식별할 수 있습니다.

General_Category 하위에는 아래와 프로퍼티들을 갖고 있기 때문에, 문자가 알파벳, 숫자, 구두점, 기호, 공백 등에 속하는지를 확인할 수 있습니다.

  • Letter: 알파벳 문자
  • Number: 숫자
  • Punctuation: 구두점
  • Symbol: 기호
  • Separator: 구분자 (예: 공백)
  • Other: 기타 범주에 속하는 문자들

Swift 에서도 이 값들을 통해 특정 유니코드가 이 속성에 해당하는지 판별 할 수 있습니다.

print("naljin".hasMatchedToPropertyValue("Number")) // false
print("123".hasMatchedToPropertyValue("Number")) // true

print("naljin".hasMatchedToPropertyValue("Separator")) // false
print(" ".hasMatchedToPropertyValue("Separator")) // true

extension String {
func hasMatchedToPropertyValue(_ unicodePropertyValue: String) -> Bool {
return self.range(of: "\\p{\(unicodePropertyValue)}", options: .regularExpression) != nil
}
}

재미있는건 (사실 재미없음) Swift 에서도 몇몇개의 유니코드 스칼라의 분류를 enum 으로 정의하고 있습니다.

enum Unicode.GeneralCategory을 들어가보면 방금 우리가 살짝 살펴봤던 General_Category 하위의 프로퍼티들이 case 로 정의되어 있네여

이 값을 확인하기 위해서는 Unicode.Scalar.Properties struct 의 generalCateogry 를 접근하면 되는데요,,! 역시 코드로 보여드리는게 이해가 빠르겠죠?

print("1".first?.unicodeScalars.first?.properties.generalCategory) // .decimalNumber
print("a".first?.unicodeScalars.first?.properties.generalCategory) // .lowercaseLetter
print("가".first?.unicodeScalars.first?.properties.generalCategory) // .otherLetter
print(" ".first?.unicodeScalars.first?.properties.generalCategory) // .spaceSeparator

이렇게 특정 유니코드가 GeneralCategory 의 어떤 프로퍼티에 해당하는지를 알아낼 수 있습니다.

그리고 아까 애플 문서에서 봤던 유니코드 분류 중에는 NumericType 도 있었잖아요?

따라서 아래와 같은 코드를 통해, 특정 유니코드가 numericType 분류에서는 어떤 프로퍼티에 해당하는지도 알아낼 수 있습니다.

print("1".first?.unicodeScalars.first?.properties.numericType) // .decimal
print("①".first?.unicodeScalars.first?.properties.numericType) // .digit
print("Ⅳ".first?.unicodeScalars.first?.properties.numericType) // .numeric
print("가".first?.unicodeScalars.first?.properties.numericType) // nil

(decimal, digit, numeric 의 예시들에는 어떤 것들이 있는지는 챗지피티한테 물어보면 잘 알려줍니당)

그렇다면 우리의 메인 관심사였던 Hangul 프로퍼티는 어느 분류에 속해있을까요? 바로 바로~~! Script 인데요! 이곳에 속하는 프로퍼티들을 통해 문자가 어떤 문자 체계(스크립트)에 속하는지를 식별할 수 있습니다.

Script 하위에는 아래와 같은 프로퍼티 값들이 있기 때문에, 문자가 라틴 알파벳, 한글, 일본어 카타카나 등 어디에 속하는지를 확인할 수 있습니다.

  • Latin: 라틴 알파벳
  • Han: 한자
  • Hiragana: 일본어 히라가나
  • Cyrillic: 키릴 알파벳
  • Arabic: 아랍어

이전에 GeneralCategoryNumericType 같은 분류가 enum 으로 정의되어 있것처럼, Script 도 정의되어 있었으면 좋았겠지만..? 일단 없으니까, 아쉬운대로 아래와 같이 "Hangul" 프로퍼티 명을 바로 입력해서 한글 여부를 판단할 수 있었던거죠!

print("가".hasMatchedToPropertyValue("Hangul")) // true
print("A".hasMatchedToPropertyValue("Hangul")) // false

extension String {
func hasMatchedToPropertyValue(_ unicodePropertyValue: String) -> Bool {
return self.range(of: "\\p{\(unicodePropertyValue)}", options: .regularExpression) != nil
}
}

만약 swift 에서 Script 에 해당하는 분류도 정의되어 있었다면 요런식으로 판단할 수 있지 않았을까요? ㅎ_ㅎ

print("가".first?.unicodeScalars.first?.properties.script) // .hangul

script 가 없는게 아쉽긴 하지만, Unicode.Scalar.Properties 에는 generalCategory, numericType 과 같은 분류 외에도, isEmoji, isHexDigit, isWhiteSpace, isMath 와 같은 다양한 값들이 정의되어 있습니다. 관심 있으신 분들은 문서 ㄱㄱ!

마무리

뭔가.. 한글을 판별하는데 이름이 Korean 이 아니라 정-직하게 Hangul 인게 조금 신기한 부분.. ㅎ 요 맥락을 따라서 애플에서도 hangulWordPriority 등으로 프로퍼티 이름을 지었던걸까요..?

hoxy.. 다른 유니코드 프로퍼티 값들도 궁금하시다구여?! 그렇다면 PropertyValueAliases 사이트를 참고하세요!

그럼 20000!

참고

https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt

--

--