Как удалить все блоки цитат bbcode определенного пользователя из текста?

Я ищу, чтобы удалить цитаты, сделанные с BBCode в PHP, как этот пример:

a sdasdsa dfv rdfgrgre gzdf vrdg
sdfsd fdsf dsf sdf[/quote] the rest of the post text

Я смотрю на создание системы блокировки, поэтому пользователям не нужно видеть контент от тех, кого они не хотят. Так, скажем, «testuser» заблокирован, они не хотят, чтобы вся эта часть в кавычках, включая вторую вложенную цитату, была частью основной цитаты.

Таким образом, пост останется только с:

остальная часть текста поста

Мне интересно, как лучше это сделать. Я надеялся на регулярное выражение, но это сложнее, чем я думал, у меня есть такая попытка:

/\
(.*)\[\/quote\]/is

Однако тогда он фиксирует все теги конечных кавычек.

Есть ли альтернативный метод, который быстро или хорошее решение для моего регулярного выражения?

Подводя итог: удалите первоначальную цитату из заблокированного пользователя и все, что находится внутри этой цитаты, но ничего больше вне ее.

-2

Решение

Насколько я могу судить, это не простой процесс. Вот мои шаги …

  1. использование preg_split() разделить входную строку тремя способами: открывающие кавычки, закрывающие кавычки и другие. Я разделяю открывающие и закрывающие теги, но использую DELIM_CAPTURE сохранить их в выходном массиве и в исходной позиции / порядке. NO_EMPTY используется для того, чтобы в цикле foreach не было бесполезных итераций.
  2. Выполните цикл по сгенерированному массиву и найдите пропущенное имя пользователя.
  3. Когда цитата целевого пользователя найдена, сохраните начальный индекс этого элемента и установите $open до 1.
  4. Всякий раз, когда новый открывающий тег цитаты найден $open увеличивается
  5. Всякий раз, когда найден новый закрывающий тег цитаты $open уменьшается.
  6. Как только $open достигает 0, $start а также end индексы подаются к range() создать массив, заполненный числами между двумя точками.
  7. array_flip(), конечно, перемещает значения в клавиши.
  8. array_diff_key() удаляет диапазон точек из массива, сгенерированного preg_split(),
  9. Если все пойдет гладко, implode() склеит подстроки вместе, сохранив только нужные компоненты.

Код: (демонстрация)

/*
This function DOES NOT validate the $bbcode string to contain a balanced number of opening & closing tags.
This funcion DOES check that there are enough closing tags to conclude a targeted opening tag.
*/
function omit_user_quotes($bbcode,$user){
$substrings=preg_split('~(\[/?quote[^]]*\])~',$bbcode,NULL,PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
$opens=0;  // necessary declaration to avoid Notice when no quote tags in $bbcode string
foreach($substrings as $index=>$substring){
if(!isset($start) && $substring=="
"){ // found targeted user's first opening quote $start=$index; // disqualify the first if statement and start searching for end tag $opens=1; // $opens counts how many end tags are required to conclude quote block }elseif(isset($start)){ if(strpos($substring,'[quote=')!==false){ // if a nested opening quote tag is found ++$opens; // increment and continue looking for closing quote tags }elseif(strpos($substring,'
')!==false){ // if a closing quote tag is found --$opens; // decrement and check for quote tag conclusion or error if(!$opens){ // if $opens is zero ($opens can never be less than zero) $substrings=array_diff_key($substrings,array_flip(range($start,$index))); // slice away unwanted elements from input array unset($start); // re-qualify the first if statement to allow the process to repeat } } } } if($opens){ // if $opens is positive return 'Error due to opening/closing tag imbalance (too few end tags)'; }else{ return trim(implode($substrings)); // trims the whitespaces on either side of $bbcode string as feature } } /* Single unwanted quote with nested innocent quote: */ /*$bbcode='
a sdasdsa dfv rdfgrgre gzdf vrdg
sdfsd fdsf dsf sdf[/quote] the rest of the test'; */ /* output: the rest of the test */ /* Complex battery of unwanted, wanted, and nested quotes: */ $bbcode='
Keep this
Don\'t keep this because
said don\'t do it
... like that\'s a good reason
It\'s tricky business, no?
[/quote][/quote] [/quote] Let\'s remove a second set of quotes
Another quote block
Let\'s do a third quote inside of my quote...
Another quote block
[/quote] This should be good, but What if
quotes himself
inside of his own
quote[/quote]?'; /* output:
Keep this
Let's remove a second set of quotes
Let's do a third quote inside of my quote...
This should be good, but What if ? */ /* No quotes: */ //$bbcode='This has no bbcode quote tags in it.'; /* output: This has no bbcode quote tags in it. */ /* Too few end quote tags by innocent user: (No flag is raised because the targeted user has not quoted any text) */ //$bbcode='This
has not end tag.'; /* output: This
has not end tag. */ /* Too few end quote tags by unwanted user: */ //$bbcode='This
has not end tag.'; /* output: Error due to opening/closing tag imbalance (too few end tags) */ /* Too many end quote tags by unwanted user: (No flag is raised because the function does not validate the bbcode text as fully balanced) */ //$bbcode='This
has too many end
tags.[/quote]'; /* output: This tags.[/quote] */ $user='testuser'; echo omit_user_quotes($bbcode,$user); // omit a single user's quote blocks /* Or if you want to omit quote blocks from multiple users, you can use a loop: $users=['mickmackusa','NaughtySquid']; foreach($users as $user){ $bbcode=omit_user_quotes($bbcode,$user); } echo $bbcode; */
1

Другие решения

То, что вы хотите, не возможно с одним регулярным выражением. Я бы порекомендовал сканировать файл, пока не найдете

, После того, как вы найдете его, установите логическое значение для начала фильтрации и счетчик равным 1. Увеличьте счетчик для каждого
тег, с которым вы сталкиваетесь после того, как логическое значение истинно. Уменьшить счетчик для каждого
тег, с которым вы сталкиваетесь. Когда счетчик достигнет 0, измените логическое значение для фильтрации на false.

Вот какой-то судокод. Возможно, вам придется изменить его в зависимости от вашего приложения, но я думаю, что он показывает общий алгоритм для использования.

filtering = false
counter = 0
for each line:
if line contains "
"filtering = true counter = 0 if line contains "[quote="counter += 1 if line contains "
counter -= 1 if counter = 0 filtering = false if not filtering print line
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector