Developer/C#, 닷넷

C# 채팅 비속어 필터링 처리

우주로그 2022. 8. 9.

york.txt
0.00MB

우리가 게임 등 온라인 상에서 채팅을 하게 되면 온갖 비속어와 마주치게 됩니다.

그래서 대부분 시스템들에서 채팅 할 때 비속어에 대해 필터링을 하고 있습니다.

 

C#에서 비속어 목록 파일을 읽어 문구에 비속어가 있는 경우 ***로 필터링 되도록 구현해보도록 하겠습니다.

1. 비속어 목록 파일 읽기

public static List<string> words = new List<string>();
public static string masking;
// 비속어 설정 파일 로딩
        
public static StreamReader reader = new StreamReader(Directory.GetParent(Environment.CurrentDirectory).Parent.FullName +@"\york.txt");
public static int maxLength = 1;

public static void FilterLoad()
   {
       // 파일 읽기
       // 마스킹 처리 길이 계산
       while (!reader.EndOfStream)
          {
              var line = reader.ReadLine();
              words.Add(line);

              if (maxLength < line.Length)
                  maxLength = line.Length;
          }
          for (int i = 0; i <= maxLength; i++)
              masking += "*";
    }

StreamReader을 이용해 비속어목록 text 파일을 읽어줍니다.

실제 욕으로 할 수는 없으니, 첨부된 "york.txt"를 다운받아 사용합니다.

해당 파일에는 "강아지"라는 용어가 비속어로 지정되어 있습니다.

 

2. 필터링 처리

public static string MessageFilter(string message)
        {
            // 필터 확인을 위한 공백 제거
            string replaceMessage = message.Replace(" ", "");
            // 메시지 공백 원복을 위한 공백 위치 정보 저장
            List<int> blankIndex = new List<int>();
            var matches = Regex.Matches(message, " ");
            // 공백 위치 확인
            foreach (Match item in matches)
            {
                blankIndex.Add(item.Index);
            }
            // 메시지 첫자부터 비교
            for (int i = 0; i < replaceMessage.Length; i++)
            {
                for (int j = replaceMessage.Length - i; j > 1; j--)
                {
                    // 비속어 목록 비교
                    for (int k = 0; k < words.Count; k++)
                    {
                        // 비속어 포함 여부
                        if (words[k] == replaceMessage.Substring(i, j))
                        {
                            // 비속어 길이만큼 ** 변경
                            replaceMessage = replaceMessage.Replace(words[k], masking[..words[k].Length]);
                        }
                    }
                }
            }
            foreach (int i in blankIndex)
            {
                // 기존 공백 복구
                replaceMessage = replaceMessage.Insert(i, " ");
            }
            return replaceMessage;
        }

입력되는 텍스트와 비속어 목록의 비교를 위해 먼저 입력되는 텍스트의 공백을 모두 제거해줍니다.

그리고 마스킹 이후 길이 복원을 위해 공백이 어디 있는지 위치 정보를 저장합니다.

 

이후 for문을 이용해 입력한 글을 파싱하면서, 목록과 순차적으로 비교를 해줍니다.

비속어를 찾은 경우 비속어 길이만큼 **로 마스킹 처리합니다.

 

마지막으로 기존 공백을 복구해서 return 해줍니다.

 

3. 테스트 실행

    class Program
    {
        static void Main(string[] args)
        {
            string text1 = "강아지야 안녕";
            string text2 = "강  아  지  야 안녕";
            FilterService.FilterLoad();
            Console.WriteLine(FilterService.MessageFilter(text1));
            Console.WriteLine(FilterService.MessageFilter(text2));

        }
    }

"강아지라는 용어가 비속어로 설정했다고 했었죠.

이제 "강아지"라는 용어와 "강 아 지" 이렇게 공백이 있는 비속어를 처리하면 아래와 같이 결과가 나옵니다.

 

 

댓글