Pull to refresh

Определяем «неправильные» слова при борьбе со спамом

Reading time3 min
Views6.3K
При борьбе со спамом на форуме возникла идея автоматически отлавливать слова, внешне похожие на «нормальные», но фактически отличающиеся от шаблонных, имеющихся в базе стоп-слов. Делается это путём замены кириллических символом на латиницу и наоборот. Например, «Пpoдaeм бeтoн» и «Продаем бетон» только внешне выглядят одинаково, а на самом деле они отличаются друг от друга.
Вот я и написал небольшую функцию для уменьшения энтропии Вселенной, которая определяет (если сможет) язык, на котором написано слово, и заменяет его на нормальное. Затем проверяем это слово по списку стоп-слов и принимаем решение, запрещённое оно или нет :)

(Красным цветом помечается кириллица, синим- латиница или цифры)

В подробности кода на C# вдаваться не буду, думаю, что всё будет понятно.
Конструктивным предложениям и замечаниям буду рад :)

public string CheckWord(string word, out string lang, out bool Changes)
{
  lang = "?";
  string newword = word;
  string OnlyRu = "БбвГгДдЁёЖжЗзИиЙйЛлмнПптУФфЦцЧчШшЩщЪъЫыЬьЭэЮюЯя";<br>
  string OnlyEn = "DdFfGghIiJjLlNQqRrSstUVvWwYZz";
  string Rus = "АаВЕеКкМНОоРрСсТуХхЗО1тиа@пь";
  string Eng = "AaBEeKkMHOoPpCcTyXx30imu@anb";

  bool IsRu100percent = false;
  foreach (char c1 in word)
    foreach (char c2 in OnlyRu)
      IsRu100percent = IsRu100percent || (c1 == c2);
  
  if (IsRu100percent)
  {
    lang = "ru";
    
    //Конвертируем все сомнительные символы в русские
    for (int i = 0; i < word.Length; i++)
      if (Eng.IndexOf(word[i]) >= 0)
      {
        //помечаем word[i] как "фальшивый"
      }
    for (int i = 0; i < Rus.Length; i++)
      newword = newword.Replace(Eng[i], Rus[i]);
  }
  else
  {
    bool IsEn100percent = false;
    foreach (char c1 in word)
      foreach (char c2 in OnlyEn)
        IsEn100percent = IsEn100percent || (c1 == c2);
    if (IsEn100percent)
    {
      lang = "en";
      //Конвертируем все сомнительные символы в английские
      for (int i = 0; i < word.Length; i++)
        if (Rus.IndexOf(word[i]) >= 0)
        {
          //помечаем word[i] как "фальшивый"
        }
      
      for (int i = 0; i < Eng.Length; i++)
        newword = newword.Replace(Rus[i], Eng[i]);
      
    }
  }
  //Были ли замены?
  Changes = newword != word;
  newword = newword.ToLower();
  _SelectionColor = lang == "ru" ? Color.Red : lang == "en" ? Color.Blue : Color.Black;
  return newword;
}

* This source code was highlighted with Source Code Highlighter.



Вызов происходит просто:
string lang;
bool changes;
string re = "[\\w\\@]+";
Regex rx = new Regex(re, RegexOptions.IgnoreCase | RegexOptions.Singleline);
Match m = rx.Match("Пpoдaeм бeтoн");
while (m.Success)
{
  string newWord = CheckWord(m.ToString(), out lang, out changes);
  m = m.NextMatch();
}

* This source code was highlighted with Source Code Highlighter.
Tags:
Hubs:
+31
Comments32

Articles