늘 느끼는 거지만 클라이언트의 어처구니 없는 요구사항은 개발자의 실력 향상에 큰 도움이 됩니다.ㅎㅎㅎ 어쩔때는 이 바닥의 기술적인 내용을 전혀 모르는 사람들의 아이디어와 요구들이 매우 참신 할 때가 많습니다. 오히려 오래 작업한 사람들은 선입견과 자신의 지식에 사로 잡혀 시작도 안해보고 이거는 이래서 안되고~ 이거는 저래서 안된다~ 라고 하게 되죠.
여튼 이번에도 지옥같은 일정으로 진행되고 있는 작업 하나가 있는데 저희 회사 진짜 호주인 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 문이 더 빨라지는 겁니까? ㅎㅎㅎ
당연히 언제나 For가 빠름. 준호의 로직이 3중으로 루프를 돌리니 느릴뿐. 스캐너의 기본도 안배우고 마구 짜서 그런거라는..