티스토리 뷰

iOS

iOS ) 한글 분해와 조사 판별

Zedd0202 2018. 4. 6. 19:35
반응형

안녕하세요 :) Zedd입니다.
요새 글을..잘 못쓰고 있는데 ㅎ 틈틈이 쓰고는 있긴한데 이게 마무리가 잘 안되네요
오늘 해보면 재밌을 것 같은게.. 생각나서 해보려고 합니댜
바로 “한글 분해와 조사 판별

애써 생각해낸..제목..........뭐라해야되지 이걸,ㄹ

음..아직 만든건 아닌데 제가 지금 만들고 싶은건 텍스트필드에 어떤 텍스트를 입력하는데 이건 무조건 한글이어야 합니다. 왜냐면 조사를 붙힐거니까....

바로 텍스트필드에 한글을 입력하면 해당 한글 문자열에 알맞는?.. 을/를 조사를 붙혀주는 앱...!!!
원래 시스템은 한글을 저장할 때 “가”라고 저장하지 않고 “ㄱ ㅏ”라고 저장하니까...


Flow는 한글을 먼저 분해하고, 분해한 지막 걸 봐서 뭐 어케어케 하면 되지 않을까??
이제까지 입코딩;;;;이고 집가서 만들어봐야함

네 집에왔으니 만들어봅시다. 금요일이라니....늦게자도 돼서 행-복


일단 텍스트필드에는 무조건 한글이 들어온다고 가정할게요.

오늘의 핵심은 조사를 어떻게 붙히느냐임



<NSString.CompareOptions>글에서도 말했듯이, iOS?그러니까 우리의 시스템..은 



똑같은 문자지만 이렇게 저장을 하나로 저장 할 수도 있고, 걔를 분해해서 저장할 수도 있죠.

한글도 마찬가지 입니다.



ㅈ ㅔ 이것도 “제”고 제도 “제”입니다.



둘다 “제”이기 때문에 똑같음 ㅎ


암튼 이걸 말한이유는....분해를 해야 하기 때문ㅇ...

만약에 “개발자”라는 텍스트가 들어오면, 우리는 맨 마지막 Character인 “자”만 필요하죠?

여기에 받침이 있냐 없냐에 따라 은/는 또는 을/를 막 이런거를 결정하니까요. 



func textFieldShouldReturn(_ textField: UITextField) -> Bool {


        guard let text = textField.text else { return false }

        self.myLabel.text = text + ( self.splitText(text: text) ? "을" : "를" )

        return true

    }


textfield delegate메소드인 textFieldShouldReturn에서 처리할게요. 최대한 간단하게 만든다.

저기서 splitText라는 저 메소드를 불러서 ? :를 검사하는거보니 splitText는 Bool타입을 리턴하겠네요.

사실 굉장히.....간단하게..생각 할 수 있는게


ex) 개발자 -> “자” -> ㅈ ㅏ 

ex) 아이폰 -> “폰” -> ㅍ ㅗ ㄴ 


세글자냐 두글자냐만 보면됨....ㅎ 


Q : 엥 그럼 “소방관”은? ㄱ ㅗ ㅏ ㄴ <- ?

A : ㄴㄴ ㅘ 이 있음 -> ㄱ ㅘ ㄴ 이 된다. 



그니까 신경 안써도댐


그럼 splitText를 구현하러 가봅시다.



 func splitText(text: String) -> Bool {


guard let text = text.last else { return false }



일단..text가 들어오면 마지막꺼만 필요하기 때문에 뽑아줍니다. (text.last는 옵셔널을 리턴하기 때문에.) -> 만약 빈 문자열을 누르고 엔터를 치면 false가 리턴돼서 “를”만 나오는 이슈가 있긴 하지만...넘어가겠습니다.


 

func splitText(text: String) -> Bool {

        guard let text = text.last else { return false }


        let val = UnicodeScalar(String(text))?.value

        guard let value = val else { return false }


그리고 뒤에서 UnicodeScalar의 Value가 필요하기 때문에 마지막 글자의 unicode value를 뽑아주고, 이 역시 옵셔널을 리턴해주므로 guard로 뽑아줍니다.

<Unicode to Int/Int to Unicode>참고



 

func splitText(text: String) -> Bool {

        guard let text = text.last else { return false }


        let val = UnicodeScalar(String(text))?.value

        guard let value = val else { return false }


let x = (value - 0xac00) / 28 / 21

        let y = ((value - 0xac00) / 28) % 21

        let z = (value - 0xac00) % 28


let i = UnicodeScalar(0x1100 + x) //초성

        let j = UnicodeScalar(0x1161 + y) //중성

        let k = UnicodeScalar(0x11a6 + 1 + z) //종성





https://soooprmx.com/archives/2165를 참고해주세요. 
요약하자면, 한글은 유니코드에서 0xAC00에서 0xD7A3 사이의 코드 값을 가지고, 초성, 중성, 종성의 유니코드를 구하려면 0xAC00에서 떨어진 위치를 구해야 하기 때문에 저런 식이 나오는 겁니다.

x, y, z를 print해볼까요?


let x = (value - 0xac00) / 28 / 21

        let y = ((value - 0xac00) / 28) % 21

        let z = (value - 0xac00) % 28


        print(x,y,z)// -> 11 0 4



초성

ㅎ 

 0

1

2

10 

11 

12 

13 

14 

15 

16 

17 

18 


중성

ㅏ 

ㅐ 

ㅑ 

ㅒ 

ㅓ 

ㅔ 

ㅕ 

ㅖ 

ㅗ 

ㅘ 

ㅙ 

ㅚ 

ㅛ 

ㅜ 

ㅝ 

ㅞ 

ㅟ 

ㅠ 

ㅡ 

ㅢ 

ㅣ 

0

1

2

10 

11 

12 

13 

14 

15 

16 

17 

18 

19 

20 


종성

 

ㄱ 

ㄲ 

ㄳ 

ㄴ 

ㄵ 

ㄶ 

ㄷ 

ㄹ 

ㄺ 

ㄻ 

ㄼ 

ㄽ 

ㄾ 

 ㄿ

ㅀ 

ㅁ 

ㅂ 

ㅄ 

ㅅ 

ㅆ 

ㅇ 

ㅈ 

ㅊ 

ㅋ 

ㅌ 

ㅍ 

ㅎ 

0

4 

10 

11 

12 

13 

14 

15 

16 

17 

18 

19 

20 

21 

22 

23 

24 

25 

26 

27 


출처: http://hanggoo.tistory.com/10 [핸꾸]




 

func splitText(text: String) -> Bool {

        guard let text = text.last else { return false }


        let val = UnicodeScalar(String(text))?.value

        guard let value = val else { return false }


let x = (value - 0xac00) / 28 / 21

        let y = ((value - 0xac00) / 28) % 21

        let z = (value - 0xac00) % 28


let i = UnicodeScalar(0x1100 + x) //초성

        let j = UnicodeScalar(0x1161 + y) //중성

        let k = UnicodeScalar(0x11a6 + 1 + z) //종성




사실 이것만 필요하지만......


Q : 아니 아까 “제” 같은건 ㅈ ㅔ 이렇게 두개만 나오잖아; z가 나올 수 있어?


종성

 

ㄱ 

ㄲ 

ㄳ 

ㄴ 

ㄵ 

ㄶ 

ㄷ 

ㄹ 

ㄺ 

ㄻ 

ㄼ 

ㄽ 

ㄾ 

 ㄿ

ㅀ 

ㅁ 

ㅂ 

ㅄ 

ㅅ 

ㅆ 

ㅇ 

ㅈ 

ㅊ 

ㅋ 

ㅌ 

ㅍ 

ㅎ 

0

10 

11 

12 

13 

14 

15 

16 

17 

18 

19 

20 

21 

22 

23 

24 

25 

26 

27 


종성이 없을 경우 z는 0으로 나옵니다.


그럼 i, j, k는 안구해도 되겠지만...그냥 있길래..해봤습니다.

i, j, k는 결국 UnicodeScalar로 값을 넘겨줬으니, “안”같은건 ㅇ ㅏ ㄴ. 

각각을 뜻하는 유니코드값이 나오게 됩니다.


만약 “제”같은걸 입력했다면(=종성이 없는 걸 입력했다면) 마지막 k는 항상 \u{11A7}이 나오게 됩니다. 


z가 0인지 아닌지를 판별해서 return값을 넘겨주도록 해볼까요?





XD




guard let end = k else { return false}

        if end.value == 4519 {

            return false

        }

        return true


이렇게 해주는 방법도 있지만...더러우니 하지맙시다. 그냥 z가 0인지 아닌지만 보면 되니까...그게 자명하니까?

아무튼 의외로 쉽죠??

뭐 은/는도 동일하게 하면 될 것 같아요 :)



반응형