// На входе:
// Контейнер со словами, которые нужно найти в строке
// Автор сообщения
// Символ побайтовой замены найденного слова
// Буфер и его размер
public void CheckOnBW(ArrayList aContainer, int iClient, int iSymbol, char[] buffer, int iLen)
{
static int iIndex, iPos;
static char
szBuffer[PMP], // Временное хранилище значения на входе
szPhrase[PMP], // Хранилище для фраз из контейнера
szPoscorrect[PMP]; // Хранилище содержимого при корректировки значения
strcopy(SZ(szBuffer), buffer);
static Regex hRegex;
if(!hRegex){
hRegex = CompileRegex("[^a-zA-Z0-9а-яА-Я_]", PCRE_UTF8);
}
for(int i; i < aContainer.Length; i++)
{
aContainer.GetString(i, SZ(szPhrase));
// Удостоверимся, что это имеет смысл
if(!szPhrase[0])
continue;
// В данном случае, а именно в GFilters, фильтр по полному совпадению осуществляется со знаком '~'
// Поэтому, учитываем смещение и получаем вхождение, если оно есть
if(szPhrase[0] == '~' && (iIndex = UTF8StrContains(szBuffer, szPhrase[1], false)) != -1)
{
// Копируем нашу строку в буффер для корректировки
strcopy(SZ(szPoscorrect), szBuffer);
/*
Ищем начало нашего слова.
Поскольку мы ищем лишь слова с полным совпадением, то нам необходимо убедиться, что
Первое вхождение и есть начало нашего слова.
*/
SearchStart(hRegex, iIndex, SZ(szPoscorrect));
// Ищем конец нашего слова.
SearchEnd(hRegex, iIndex, szPoscorrect);
/*
Заменяем его побайтово.
В условии нужно учитывать смещение согласно синтаксису GFilters, т.к. szPhrase[0] = '~'
По поводу кастомной функции:
* Её нет в стд либе UTF-8-string.
* Стд функция ReplaceString() имеет теже проблемы, что и функции, которые исправлены в UTF-8-string
* Функция неменого изменена
*/
if(UTF8StrEqual(szPhrase[1], szPoscorrect, false)){
UTF8ReplaceString(SZ(szBuffer), szPhrase[1], iSymbol);
}
}
}
// Проверка последовательности.
if(!UTF8strcmp(szBuffer, buffer, false)){
return;
}
// Заполняем основной буффер на выход
strcopy(buffer, iLen, szBuffer);
}
// Вход:
// Регеx выражение
// Позиция совпадения
// Строка целиком и ее размер
void SearchStart(Regex &hLocal, int &iPointer, char[] szPhrase, int iLen)
{
// Вектор движения: 0 <- iPointer
// Не имеет смысла, если позиция уже 0
if(!iPointer)
return;
// Ищем количество совпадений по регексу
static int iMatchCount;
iMatchCount = hLocal.MatchAll(szPhrase);
// Если таковых нет, то это одно большое слово или несколько: один два три -> одиндватри
if(iMatchCount < 1)
{
iPointer = 0;
return;
}
// Перебор
for(int i; i < iMatchCount; i++)
{
/*
Немного на тему, как работает MatchOffset:
Данный метод возвращает смещение конца найденного выражения.
*/
if(hLocal.MatchOffset(i) > iPointer)
{
/*
Согласно условию выше сдвигаем вхождение
*/
iPointer = (!i) ? 0 : hLocal.MatchOffset(i-1);
break;
}
}
// Сохраняем наши достижения
strcopy(szPhrase, iLen, szPhrase[iPointer]);
}
// Вход:
// Регеx выражение
// Позиция вхождения
// Буффер
void SearchEnd(Regex &hLocal, int &iPointer, char[] szPhrase)
{
// В целом, действия повторяются
static int iMatchCount;
iMatchCount = hLocal.MatchAll(szPhrase);
// Отсутствие совпадений по выражению, конец = длине строки.
// В ином случае, это первое совпадение с оффсетом - 1.
if(iMatchCount < 1)
iPointer = strlen(szPhrase);
else iPointer = hLocal.MatchOffset(0) - 1;
// Обрываем
szPhrase[iPointer] = 0;
}