[React/node] 한글 욕설 필터링 기능 구현하기 (node csv 파일 변환)
Code/React - Node

[React/node] 한글 욕설 필터링 기능 구현하기 (node csv 파일 변환)

반응형

결과물 미리보기

 

자체 로그인 기능을 위한 기획 회의에 참여해 한창 얘기를 나누던 도중

나 : 닉네임에 욕설 필터링이 필요하지 않을까요?

PM : 오!!!!!!! 아~~~~~ 예 그래야겠네요

나 : 어느정도까지 커버할 수 있는지 감이 잘 안 와서..리서치 후에 내용 공유 드리겠습니다

 

여러 정보를 찾아 보았을 때

 욕설 필터링은 자체적으로 자연어 처리를 이용해 고도화된 엔진을 사용하여 검수하는 방법과 기타 라이브러리를 사용하는 방법이 있었는데

우선 자연어 처리를 하는 것은 현 상황에 적절하지 않은 방안이었기에, 라이브러리를 찾아보기 시작했다.

bad-words (support only english)

https://github.com/web-mech/badwords

 

GitHub - web-mech/badwords: A javascript filter for badwords

A javascript filter for badwords. Contribute to web-mech/badwords development by creating an account on GitHub.

github.com

 

우선 한글을 지원하는 욕설 필터링은 없었기에 그렇다면 가장 방대한 욕설 데이터를 가지고 있는 라이브러리가 필요하다 판단,

bad-words 라이브러리를 찾아냈다.

그렇다면 영문이 아닌 한글 필터링은 어떻게 할 것인가? 이가 없으면 잇몸으로라도 해야 하기 때문에 기획자분께 욕설 리스트 정리 후 공유를 부탁드렸다.

욕설 전문가인 동료에 의해 욕설 리스트를 쉽게 확인할 수 있었고 기획자 분께서 최종적으로 리스트 욕설 추가, 삭제 및 검증 후 리스트를 전달해 주셨다.

csvToTs.js

const csv = require('csv-parser');
const {createReadStream, writeFile} = require('fs');

const dataArray = [];

createReadStream('src/converter/csv/profanity_words.csv')
  .pipe(csv())
  .on('data', row => {
    dataArray.push(row['word']);
  })
  .on('end', () => {
    writeFile(
      'src/converter/ts/profanityWords.ts',
      `export const PROFANITY_WORDS = ${JSON.stringify(dataArray)};`,
      'utf8',
      function (err) {
        console.log(
          err || `profanity_words.csv -> profanityWords.ts 변환 성공`,
        );
      },
    );
  });

추가된 욕설 리스트를 어떻게 관리할까 하다가, docs 문서에 있는 욕설들을 csv 파일로 변환한 뒤 스크립트를 실행하면 ts 파일 상수로 욕설을 요소로 갖는 배열을 만들어내도록 구현했다.

node의 createreadStream / writeFile api 와 csv-parser 를 사용해 구현해냈다

csv 파일을 변환한 후 각 데이터를 배열에 담아내고, 데이터를 모두 읽어 오면 profanityWords.ts 파일을 생성해 dataArray 를 익스포트 할 수 있는 구조로 만드는 코드이다.

(csv 파일 typescript 로 변환)

package.json

scripts 에 convert:csv 를 정의해 csvToTs.js 파일을 실행할 수 있도록 추가했고

스크립트 실행 시 아래와 같이 다소 숭한 파일이 생성된다.

profanityWords.ts

욕설을 추가 또는 삭제할 일이 생긴다면 csv 파일만 수정하고 스크립트 실행만 하면 된다.

checkProfanityWord() - 욕설 검증 함수

import Filter from 'bad-words';

export const checkProfanityWord = (word: string) => {
  const filter = new Filter();

  return (
    filter.isProfane(word) ||
    PROFANITY_WORDS.some(_word => (_word ? word.includes(_word) : false))
  );
};

bad-words 라이브러리가 addWords 메소드를 지원하고 있는데 보니까 메소드를 사용해도 한글은 추가되지 않아 비효율적이지만 리스트에 존재하는 영문이라도 추가 될 수 있도록 확장 시키고 따로 정의한 PROFANITY_WORDS 를 some 을 사용해 필터링 하도록 구현했다.

 

결과물 gif

포스팅하려고 테스트하는데 '바보'가 리스트에 없었던 것 같다.

무척이나 방황하는 마우스 커서

반응형