Offensive Word Filter

늘 느끼는 거지만 클라이언트의 어처구니 없는 요구사항은 개발자의 실력 향상에 큰 도움이 됩니다.ㅎㅎㅎ 어쩔때는 이 바닥의 기술적인 내용을 전혀 모르는 사람들의 아이디어와 요구들이 매우 참신 할 때가 많습니다. 오히려 오래 작업한 사람들은 선입견과 자신의 지식에 사로 잡혀 시작도 안해보고 이거는 이래서 안되고~ 이거는 저래서 안된다~ 라고 하게 되죠.

여튼 이번에도 지옥같은 일정으로 진행되고 있는 작업 하나가 있는데 저희 회사 진짜 호주인 PM 이 해맑은 미소를 지으며 코멘트 작성시 불량단어 체크해 달랍니다. 뭐 단어 체크하는 거야 그냥 search() 한번 해주면 되니 ok 했는데 그게 끝이 아니였습니다. 유저가 쓴 코멘트에 불량단어 마다 하이라이트를 해달라는 겁니다. 오~마이~~~갓~~ 이런 알흠다운십장생을 봤나. 당장 가장 중요한 기능들도 기간내에 만들까 말까 하고만 어디서 본 건 있어 가지고~~ 여튼 해달랍니다. 물론 저는 기성개발자로서 이건 이래서 안되고 저건 저래서 안된다고 말 하고 싶었지만 아~~ 아직 그런 고차원 적인 말을 영어로 할 수가 없습니다. 그래서 마냥 울며 ok 를 했습니다.

이 필터링의 어려운 문제는 대소문자 입니다. 보통 이런 단어 필터링을 할때는 코멘트와 키워드의 대,소문자를 일치시키고 검색을 하게 되는데 이렇게 되면 유저가 쓴 원글이 수정되므로 이러한 수정없이 단어를 체크해야 했습니다. 남들 다 쉬는 토요일에 저와 구준호님이 함께 이 문제를 고민해봤습니다. 그래서 나온 결과를 공유 합니다. 제 경우는 정규표현식으로 해당단어를 치환했고 구준호님은 for 문으로 단어를 확인했습니다.

1. 정규표현식

private function checkByReg(input:String, keyword:Array):void
{
	var temp:String = input;
	for (var i:int = 0; i < keyword.length; i++)
	{
		var pattern:RegExp = new RegExp('(' + keyword[i] + ')', 'ig');
		temp = temp.replace(pattern, '$&');
	}

	_comment.textField.htmlText = temp;
}

var pattern:RegExp = new RegExp(‘(‘ + keyword[i] + ‘)’, ‘ig’); 에서 i 옵션이 중요합니다. i 는 대소문자를 구분하지 않겠다 입니다. 정규표현식이 좋은 점은 정규표현식 자체의 다양한 식을 적용 할 수 있다는 겁니다. 다만 replace 해야 하므로 위와 같은 html 을 사용 해야 합니다.

2. for 문

public function checkByFor(input:String, keyword:Array):void
{
	var format:TextFormat = new TextFormat(null, null, 0xFF0000);

	for ( var i:int = 0 ; i < input.length ; i++ )
	{
		for ( var j:int = 0 ; j < keyword.length ; j++ )
		{
			var badWord:String = keyword[j];

			if ( checkWord(i, input, badWord) )
			{
				_comment.textField.setTextFormat(format, i, i + badWord.length);
			}
		}
	}
}

private function checkWord(index:int, input:String, badWord:String):Boolean
{
	for ( var i:int = 0 ; i < badWord.length ; i++ )
	{
		var currentCharOfBadWord:String = badWord.charAt(i).toUpperCase();
		var currentCharOfInput:String = input.charAt(index + i).toUpperCase();

		if ( currentCharOfBadWord != currentCharOfInput )
			return false;
	}

	return true;
}

구준호님이 만들어 주신 로직입니다. 각 단어의 길이로 잘라서 비교하고 해당 되는 단어 부분의 TextFormat 을 바꿔 줍니다. 덕분에 몰랐던 setTextFormat 함수를 알게 되었네요. 그리고 이 함수들은 원래 목적은 불량단어 검출이였지만 하이라이트 기능을 바꾸어 써도 좋을 것 같네요.

얼마전에 히카님과 String 형에 대해서 이야기 나눈 적이 있는데 얼마 지나지 않아 이렇게 복습을 하니 참 좋네요. 다만 조건의 차이가 있기는 하겠지만 아무래도 단순비교에서는 정규식이 더 빠른 것 같은데... 히카님게 묻습니다. 언제 for 문이 더 빨라지는 겁니까? ㅎㅎㅎ

소스 다운로드

1 thought on “Offensive Word Filter”

  1. 당연히 언제나 For가 빠름. 준호의 로직이 3중으로 루프를 돌리니 느릴뿐. 스캐너의 기본도 안배우고 마구 짜서 그런거라는..

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.