Java 이모티콘 찾기, 제거 등등
web/Web

Java 이모티콘 찾기, 제거 등등

반응형

이번 프로젝트를 진행하면서 이모티콘을 제거하거나 개수를 세거나 이모티콘을 포함한 전체 텍스트 문자를 세거나하는 작업이 있었다. 처음에는 단순하게 EmojiParser를 사용해서 이모티콘을 판단하여 개수도 찾고 이모티콘을 문장에서 제거하려고 했다.

 

하지만 테스트에서 사용했던 일부 이모지에서는 큰 문제가 없었으나 새롭게 생성되는 이모지를 걸러내지 못하는 이슈가 있었다. 확인해보니 해당 라이브러리에 마지막 릴리즈 날짜는 19년도였다.

 

이모티콘은 매년 많게는 수천개가 생성되는것에 비해 해당 라이브러리의 마지막 릴리즈 노트 날짜는 너무 처량했다. 해당 라이브러리를 사용하지 못하게 되었고 다른 방법이 없는지 고민하다가 regex를 사용하는 방법 등 여러가지를 사용했었다. 

 

1. 화이트리스트 regex 사용하여 이모티콘 제거 또는 찾기

해당 링크에 나와있는 것처럼 일부 이모티콘 정규식 패턴을 찾아서 적용을 해봤으나 새롭게 생성되는 이모티콘등을 정확하게 찾아내기는 어려웠다.

 

2. 한글, 영어, 숫자, 특수문자를 모두 정규식으로 제외하고 이모티콘 갯수 세기

제목 그대로 한글, 영어, 숫자, 특수문자, 공백을 모두 제외하는 정규식을 사용해서 이모티콘의 개수를 확인하려고 시도하였으나 이모티콘의 문자를 보면 하나의 글자형태가 아니라 여러 코드의 조합으로 만들어진것을 확인할 수 있다. 그렇기에 정규식으로 이모티콘만 남겼으나 실제 이모티콘이 어느 코드 조합까지가 이모티콘인지 알수가 없었다.

출처 : https://meetup.toast.com/posts/317

 

3. 현재까지 나와있는 이모티콘의 데이터를 사전처럼 활용하기

결국 2번에서의 문제도 이모티콘 문자만 남겨놓았다고 하더라도 어디까지의 코드조합이 이모티콘인지 알수가 없기 때문에 현재까지 약속되어있는 이모지 사전을 만들어서 판별하도록 하였다. 이모티콘 사전은 가장 이모티콘 라이브러리 중 활발하게 업데이트가 되고 있는 파이썬 라이브러리에서 사용하는 이모티콘 사전을 사용했다.

 

1) 사전 파일 선정

https://github.com/carpedm20/emoji

 

GitHub - carpedm20/emoji: emoji terminal output for Python

emoji terminal output for Python. Contribute to carpedm20/emoji development by creating an account on GitHub.

github.com

최근까지 업데이트가 꾸준히 되고 있고 emoji 파일도 잘 정리되어있다. 

 

2) 이모지 사전 만들기

data_dict.py에 있는 이미지들을 모두 가져와서 코드에서 array형태로 보관하도록 처리하였다.

public static final List<String> EMOJI_DICTIONARIES = Arrays.stream(new String[] {
            "🥇",
            "🥈",
            "🥉",
            "🆎",
            "🏧",
            "🅰️",
            "🅰",
            "🇦🇫",
            "🇦🇱",
            "🇧🇷",
            "🇮🇴",
            "🇻🇬",
            "🇧🇳",
            "🇧🇬",
            "🇧🇫",
            "🇧🇮",
            "🆑",
            "🆒",
            "🇰🇭",
            "🇨🇲",
            "🇨🇦",
            "🇮🇨",
            "♋",
            "🇨🇻",
            "♑",
            "🇧🇶",
            "🇰🇾",
            "🇨🇫",
            "🇪🇦",
            "🇹🇩",
            "🇨🇱",
            "🇨🇳",
            "🇨🇽",
            "🇬🇷",
            "🇬🇱",
            "🇬🇩",
            "🇬🇵",
            "🇬🇺",
            "🇬🇹",
            "🇬🇬",
            "🇬🇳",
            "🇬🇼",
            "🇬🇾",
            "🇭🇹",
            "🇭🇲",
            "🇭🇳",
            "🇭🇰",
            "🇭🇺",
            "🆔",
            "🇮🇸",
            "🇮🇳",
            "🇮🇩",
            "🇮🇷",
            "🇮🇶",
            "🇮🇪",
            "🇽🇰",
            "🇰🇼",
            "🇰🇬",
            "🇱🇦",
            "🇱🇻",
            "🇱🇧",
            "♌",
            "🤶🏻",
            "🤶🏾",
            "🤶🏼",
            "🤶🏽",
            "🇲🇲",
            "🆕",
            "🆖",
            "🇳🇦",
            "🇳🇷",
            "🇳🇵",
            "🇳🇱",
            "🇳🇨",
            "🇳🇿",
            "🇳🇮",
            "🇳🇪",
            "🇳🇬",
            "🇳🇺",
            "🇳🇫",
            "🇰🇵",
            "🇲🇰",
            "🇲🇵",
            "🇳🇴",
            "🆗",
            "👌",
            "👌🏿",
            "👌🏻",
            "👌🏾",
            "👌🏼",
            "👌🏽",
            "🔛",
            "🅾️",
            "🅾",
            "🇴🇲",
            "⛎",
            "🅿️",
            "🅿",
            "🇵🇰",
            "🇵🇼",
            "🇵🇸",
            "🇵🇦",
            "🇵🇬",
            "🇵🇾",
            "🇵🇪",
            "🇵🇭",
            "♓",
            "🇵🇳",
            "🇵🇱",
            "🇵🇹",
            "🇵🇷",
            "🇶🇦",
            "🇷🇴",
            "🇷🇺",
            "🇷🇼",
            "🇷🇪",
            "🔜",
            "🆘",
            "♐",
            "🇼🇸",
            "🇸🇲",
            "🎅",
            "🎅🏿",
            "🎅🏻",
            "🎅🏾",
            "🎅🏼",
            "🎅🏽",
            "🇸🇦",
            "♏",
            "🏴",
            "🇸🇳",
            "🇷🇸",
            "🇸🇨",
            "🇸🇱",
            "😽",
            "😗",
            "😚",
            "😙",
            "🔪",
            "🪁",
            "🥝",
            "🪢",
            "🐨",
            "🪘",
            "🧴",
            "🪷",
            "😭",
            "📢",
            "🤟",
            "🤟🏿",
            "🤟🏻",
            "🤟🏾",
            "🤟🏼",
            "🤟🏽",
            "🏩",
            "💌",
            "🪫",
            "🧳",
            "🫁",
            "🤥",
            "🧙",
            "🧙🏿",
            "🧙🏻",
            "🧙🏾",
            "🧙🏼",
            "🧙🏽",
            "🪄",
            "🧲",
            "🔍",
            "🔎",
            "🀄",
            "♂️",
            "♂",
            "🦣",
            "👨",
            "👨‍🎨",
            "👨🏿‍🎨",
            "👨🏻‍🎨",
            "👨🏾‍🎨",
            "👨🏼‍🎨",
            "👨🏽‍🎨",
            "👨‍🚀",
            "👨🏿‍🚀",
            "👨🏻‍🚀",
            "👨🏾‍🚀",
            "👨🏼‍🚀",
            "👨🏽‍🚀",
            "👨‍🦲",
            "🧔‍♂️"
    }).sorted((a1, a2) -> Integer.compare(a2.length(), a1.length())).collect(Collectors.toList());

위 코드는 모든 이모지를 다 붙여넣기에는 4000여개 되는 코드라서 다 넣지는 않았다. 파일을 보고 넣어서 사용하면 된다. 여기서 변수 생성 시 길이가 긴 순으로 내림차순해서 정렬한 이유는 이모티콘은 여러 이모티콘을 합쳐서 하나의 이모티콘으로 표현하거나 색상을 바꾸거나 해서 사용이 가능하다. 

위 그림에서 아래 이모티콘은 위의 이모티콘에서 색상 이모티콘이 합쳐진 아래와 같은 형태이다.

그렇기 때문에 문장에서 이모티콘을 순차적으로 사전에서 찾을 때 합성 이모티콘 순서부터 기본 이모티콘 순서로 찾아야 의도에 맞는 이모티콘 개수를 찾을 수 있다. 그렇지 않을 경우 흑백 손가락 이모티콘을 한개가 아닌 두개의 이모티콘으로 판별할 수 있다.

 

3) 이모지 개수 세기 

내부적으로 생성한 이모지 사전을 활용해서 이모지 개수를 찾도록 하였다.

public static int countEmoji(String str) {
    if (str == null || str.isEmpty()) {
        return 0;
    }

    int findCount = 0;
    for (String emoji: EMOJI_DICTIONARIES) {
        if (str.contains(emoji)) {
            findCount += StringUtils.countMatches(str, emoji);
            str = str.replace(emoji, "").replaceAll(emoji, "");
        }
    }
    return findCount;
}

 

4) 이모지 제거 

public static String removeEmoji(String str) {
    if (str == null || str.isEmpty()) {
        return "";
    }

    for (String emoji : EMOJI_DICTIONARIES) {
        str = str.replace(emoji, "").replaceAll(emoji, "");
    }
    return str;
}

 

현재는 사전을 중심으로 사전만큼 n번 순회하도록 되어있어서 조금 아쉽기는 하지만 내가 생각해본 방법 중 정확하게 추출하기 위한 방법은 사전 방법이었다.

 

사전이 매 순간마다 업데이트 되는것이 아니기 때문에 모니터링 하면서 주기적으로 사전 업데이트는 필요하다는 단점은 존재한다. 다른 방식이 있다면 업데이트 해봐야겠다.

반응형