Добавление регулярных выражений в систему цензуры для C++

Я уже некоторое время пытаюсь создать систему цензуры для эмулятора WoW под названием TrinityCore. Что я в основном делаю, так это заполняю таблицу базы данных (chat_filter) "плохими словами", заполняю вектор ими при запуске и в каждой строке чата, созданной игроком, она проверяется на соответствие содержимому моего вектора. Если оно содержит плохое слово, оно заменяется ** (тогда как количество * также будет взято из столбца таблицы базы данных (todo)), и игрок получает наказание (приглушено или около того).

Теперь у меня проблемы с тем, как сделать правильный фильтр. Прямо сейчас вам нужно добавить каждую возможную комбинацию слова, которое вы можете придумать, например, "осел" также следует читать как "осел", и я понятия не имею, как это сделать!

Вот важная часть текущего кода, я пропустил извлечение БД, так как в любом случае оно не имело бы никакого смысла (и это сделало бы его менее понятным, поскольку оно находится в другом файле).

char* msg3 = strdup(msg.c_str());
char* words = strtok(msg3, " ,.-()&^%$#@!{}'<>/?|\\=+-_1234567890"); // This splits the sentence in seperated words and removes the symbols
ObjectMgr::ChatFilterContainer const& censoredWords = sObjectMgr->GetCensoredWords();

while (words != NULL && !censoredWords.empty())
{
    for (uint32 i = 0; i < censoredWords.size(); ++i)
    {  
        if (!stricmp(censoredWords[i].c_str(), words))
        {
            sLog->outString("%s", words);
            //msg.replace(msg.begin(), msg.end(), msg.c_str(), "***");
            msg.replace(msg.begin(), msg.end(), censoredWords[i].c_str(), '*');
        }
        //msg.replace(msg.begin(), msg.end(), censoredWords[i].c_str(), /*replacement*/ "***");
        //msg.replace(msg.find(censoredWords[i].c_str()), censoredWords.size(), 
    }

    words = strtok(NULL, " ,.-()&^%$#@!{}'<>/?|\=+-_1234567890");
}

Заранее спасибо,

Джаспер

PS "GetCensoredWords" возвращает вектор.

PSS 'msg' - это std::string - это АКТУАЛЬНОЕ сообщение, отправленное игроком.

1 ответ

Я хотел бы использовать std::string не char* Таким образом, управление памятью все автоматически. Это решило бы проблему утечки памяти в вашем примере кода. Boost.Algorithm предоставляет мощный boost::algorithm::split функция, которая намного лучше, чем strtok,

Невозможно хранить каждую возможную перестановку цензурированного слова, особенно если вы собираетесь перебирать весь набор слов для каждого ввода. Если вы хотите подвергнуть цензуре "fubar", вам нужно будет хранить "Fubar", "FUbar", "FuBaR", "fub4r", "FUBAR", "fubar" и т. Д. И т. Д. И т. Д.

Вместо этого вы можете хранить каждое цензурированное слово только один раз в нормализованной форме, например, "fubar", а затем преобразовывать каждое входное слово в нормализованную форму. Поэтому, если пользователь вводит "FuBaR", вы нормализуете его до "fubar", тогда вы можете сделать простой поиск в наборе цензурированных слов (который может использовать ассоциированный контейнер, так что поиск будет O(log n) или даже O(1)).)

Другие вопросы по тегам