При работе с ChatGPT в тексте иногда появляются служебные конструкции, которые не предназначены для показа читателям. Вместо нормальной ссылки или цитаты в статье можно увидеть строки вроде:
:contentReference[oaicite:1]{index=1}
[oaicite:12]
oaicite:12
【turn3search4】
Такие фрагменты называют системным мусором. Они не несут пользы для посетителя сайта, портят внешний вид статьи и могут попадать в поисковый индекс.
ChatGPT может добавлять к ответу внутреннюю разметку, которая используется для отображения источников, файлов, результатов поиска и других элементов интерфейса. В нормальной ситуации приложение преобразует эту разметку в аккуратную ссылку или значок цитирования.
Какие конструкции нужно удалять
ContentReference
Служебные цитаты <pre><code></code></pre>
Отдельные маркеры oaicite [oaicite:7] oaicite:18
Маркеры turn【turn1search2】 【turn25fetch3】
Все эти элементы можно безопасно убрать, если они попали в текст статьи как обычные символы.
Ситуация 1 — убираем мусор перед публикацией
Если ответ хранится в переменной:
{-Variable.otvet_gpt-}
сразу после получения текста можно добавить действие C# OwnCode. Оно очистит переменную перед отправкой материала в WordPress.
Последовательность действий должна выглядеть так:
string text = project.Variables["otvet_gpt"].Value;
if (string.IsNullOrEmpty(text))
{
return "";
}
// Удаляем contentReference
text = System.Text.RegularExpressions.Regex.Replace(
text,
@":contentReference\[oaicite:\d+\]\{index=\d+\}",
""
);
// Удаляем cite и filecite
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"]*",
""
);
// Удаляем отдельные oaicite
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"\[?oaicite:\d+\]?",
""
);
// Удаляем маркеры turn
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"【turn\d+[a-z]+\d+】",
""
);
// Удаляем пустые строчные HTML-теги
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"<(strong|b|em|i|code|span)>\s*</\1>",
"",
System.Text.RegularExpressions.RegexOptions.IgnoreCase
);
// Убираем пробелы перед закрывающими тегами
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"[ \t]+(?=</(?:p|li|td|th|figcaption|strong|b|em|i|code|span|a)>)",
"",
System.Text.RegularExpressions.RegexOptions.IgnoreCase
);
// Несколько пробелов заменяем одним
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"[ \t]{2,}",
" "
);
// Убираем пробел перед пунктуацией
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"[ \t]+([,.;:!?])",
"$1"
);
// Исправляем сочетание двоеточия и точки
text = System.Text.RegularExpressions.Regex.Replace(
text,
@":\.",
"."
);
// Сохраняем структуру пустых ячеек таблицы
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"<td>\s*</td>",
"<td></td>",
System.Text.RegularExpressions.RegexOptions.IgnoreCase
);
// Убираем лишние пустые строки
text = System.Text.RegularExpressions.Regex.Replace(
text,
@"(\r?\n[ \t]*){3,}",
"\r\n\r\n"
);
text = text.Trim();
project.Variables["otvet_gpt"].Value = text;
return text;
Что делает этот код
Сначала код получает содержимое переменной otvet_gpt. Затем последовательно применяет несколько регулярных выражений.
Они удаляют системные ссылки, отдельные идентификаторы и файловые цитаты. После этого код исправляет последствия очистки:
- убирает двойные пробелы;
- удаляет пробелы перед точками и запятыми;
- удаляет пустые теги вроде
<strong></strong>; - сохраняет HTML-ссылки, списки и таблицы;
- сокращает лишние пустые строки;
- записывает готовый текст обратно в переменную.
Ситуация 2 — очистка уже опубликованных записей
Если служебный мусор уже попал в опубликованные статьи, его можно удалить непосредственно из базы данных WordPress через phpMyAdmin.
В нашем случае мусор находился только в обычных записях. Поэтому во всех запросах использовалось условие:
post_type = 'post'
Благодаря этому страницы, товары WooCommerce, шаблоны и другие типы содержимого не затрагиваются.
Шаг 1. Найти записи с системным мусором
Сначала нужно проверить, в каких обычных записях встречаются служебные конструкции:
SELECT ID, post_title, post_status, LEFT(post_content, 300) AS fragment FROM wp_posts WHERE post_type = 'post' AND ( post_content LIKE '%contentReference%' OR post_content LIKE '%oaicite%' OR post_content LIKE '%filecite%' OR post_content LIKE '%turn%' ) ORDER BY ID DESC LIMIT 25;
Этот запрос ничего не изменяет. Он только показывает найденные записи и небольшой фрагмент их содержимого.
Если таблица WordPress имеет другой префикс, вместо wp_posts необходимо указать её настоящее название.
Шаг 2. Посчитать количество затронутых записей
После предварительного поиска мы посчитали количество обычных записей, содержащих основные маркеры:
SELECT COUNT(*) AS found_posts FROM wp_posts WHERE post_type = 'post' AND ( post_content LIKE '%contentReference%' OR post_content LIKE '%oaicite%' OR post_content LIKE '%filecite%' );
В нашем случае было найдено 429 записей.
Шаг 3. Определить, какие маркеры встречаются
Затем мы отдельно проверили каждый основной тип мусора:
SELECT SUM(post_content LIKE '%contentReference%') AS content_reference, SUM(post_content LIKE '%oaicite%') AS oaicite, SUM(post_content LIKE '%filecite%') AS filecite FROM wp_posts WHERE post_type = 'post';
Результат показал:
contentReference— 429 записей;oaicite— 429 записей;filecite— 0 записей.
Это означало, что во всех найденных статьях присутствовала конструкция вида contentReference.
Шаг 4. Создать резервную таблицу
Перед удалением мы сохранили копию только тех записей, которые собирались изменять:
CREATE TABLE wp_posts_backup_oaicite AS SELECT * FROM wp_posts WHERE post_type = 'post' AND post_content LIKE '%contentReference%';
phpMyAdmin после выполнения такого запроса может показать сообщение о пустом результате. Это нормально: команда создаёт таблицу, а не выводит строки на экран.
Количество сохранённых записей проверили отдельным запросом:
SELECT COUNT(*) AS backup_rows FROM wp_posts_backup_oaicite;
В резервной таблице оказалось 429 строк, то есть копия была создана успешно.
Шаг 5. Удалить конструкции contentReference
После создания резервной копии мы выполнили массовую очистку:
UPDATE wp_posts SET post_content = REGEXP_REPLACE( post_content, ':contentReference\\[oaicite:[0-9]+\\]\\{index=[0-9]+\\}', '' ) WHERE post_type = 'post' AND post_content LIKE '%contentReference%';
Запрос удаляет конструкции такого вида:
При этом изменяются только обычные записи с типом post. В нашем случае phpMyAdmin сообщил, что затронуто 429 строк.
Шаг 6. Проверить результат
После очистки мы проверили, остались ли в обычных записях конструкции contentReference или oaicite:
SELECT COUNT(*) AS remaining FROM wp_posts WHERE post_type = 'post' AND ( post_content LIKE '%contentReference%' OR post_content LIKE '%oaicite%' );
Результат:
remaining 0
Это означает, что все найденные конструкции были успешно удалены.
Шаг 7. Проверить сайт и сохранить резервную копию
После изменения базы желательно очистить кэш WordPress, кэш плагина оптимизации и CDN, если он используется. Затем нужно открыть несколько записей и проверить текст, HTML-разметку и пунктуацию.
Резервную таблицу лучше не удалять сразу. Её можно оставить на несколько дней, пока не будет подтверждено, что статьи отображаются правильно.
После окончательной проверки резервную таблицу можно удалить:
DROP TABLE wp_posts_backup_oaicite;
Таким образом, полная последовательность очистки выглядела так:
Поиск записей → подсчёт найденных статей → определение типа мусора → создание резервной таблицы → проверка резервной копии → удаление contentReference → контрольный поиск → очистка кэша и проверка сайта