Php 如何从文本中删除特定用户的所有bbcode引号块?
我希望删除PHP中使用BBCode的引号,如以下示例:Php 如何从文本中删除特定用户的所有bbcode引号块?,php,regex,substring,filtering,bbcode,Php,Regex,Substring,Filtering,Bbcode,我希望删除PHP中使用BBCode的引号,如以下示例: [quote=testuser] [quote=anotheruser]a sdasdsa dfv rdfgrgre gzdf vrdg[/quote] sdfsd fdsf dsf sdf[/quote] the rest of the post text 我正在考虑做一个屏蔽系统,这样用户就不必看到他们不想看到的内容。如果“testuser”被阻止,他们不希望整个引用部分,包括嵌套在其中的第二个引用,因为这是主引用的一部分 因此,该职
[quote=testuser]
[quote=anotheruser]a sdasdsa dfv rdfgrgre gzdf vrdg[/quote]
sdfsd fdsf dsf sdf[/quote]
the rest of the post text
我正在考虑做一个屏蔽系统,这样用户就不必看到他们不想看到的内容。如果“testuser”被阻止,他们不希望整个引用部分,包括嵌套在其中的第二个引用,因为这是主引用的一部分
因此,该职位将只剩下:
文章的其余部分
我想知道做这件事的最好方法。我希望是正则表达式,但更复杂的是,我想,我有这样的尝试:
/\[quote\=testuser\](.*)\[\/quote\]/is
但是,这将捕获所有的结束引号标记
有没有一种快速的替代方法,或者是我的正则表达式的一个好的修复方法
总而言之:删除被阻止用户的初始报价和报价内的所有内容,但不删除报价外的任何内容。单用一个正则表达式无法实现您想要的内容。我建议您扫描该文件,直到找到
[quote=testuser]
。找到后,将布尔值设置为开始过滤,并将计数器设置为1。在布尔值为真后,增加遇到的每个[quote=…]
标记的计数器。为遇到的每个[/quote]
标记递减计数器。当计数器达到0时,将用于筛选的布尔值更改为false
这是一些sudocode。您可能需要根据您的应用程序对其进行一些修改,但我认为它显示了要使用的通用算法
filtering = false
counter = 0
for each line:
if line contains "[quote=testuser]"
filtering = true
counter = 0
if line contains "[quote="
counter += 1
if line contains "[/quote]
counter -= 1
if counter = 0
filtering = false
if not filtering
print line
据我所知,这不是一个简单的过程。这是我的步骤
preg_split()。我在开始和结束标记上进行拆分,但使用DELIM_CAPTURE
将它们保留在输出数组中以及原始位置/顺序中<使用code>NO_EMPTY
,这样在foreach循环中就不会出现无用的迭代$open
设置为1$open
将递增$open
将递减$open
达到0
时,$start
和end
索引将馈送到range()
以生成一个在两点之间填充数字的数组array\u flip()
当然会将值移动到键array\u diff\u key()
从preg\u split()
生成的数组中删除点的范围内爆()
会将子串粘合在一起,只保留所需的组件因为有嵌套引号的能力,所以单靠正则表达式无法获得所需的确切功能。无法跟踪您通过的[quote=…]数量。请尝试此
(\[quote=)(.*)((\s|\s)*?(\[\/quote\])*
,因为只有第一个引号和最后一个尾端引号才是最重要的。如果使用替换,组2($2
)等于第一个引号用户名。你能写下你到底想隐藏什么吗?或者把你想要的写出来see@BelalMohammed据我所知,OP希望找到第一个quote用户的用户名,如果它与“忽略列表”类型匹配,它只会将其隐藏。@GrumpyCrouton只有在“测试的其余部分”中没有其他用户引用的情况下才会起作用,这听起来很有希望是正确的,有这样一个技巧的例子吗?我会试着写一个快速的例子,或者看看我能不能找到一个你是明星谢谢!在添加解释之前,我需要做更多的测试。非常感谢所有的帮助:)@顽皮液我现在对它很有信心。做了一些基本测试,我认为它确实如预期的那样工作,从我所能说的来看几乎完美。这太棒了!可惜我的作品被否决了,人们将来可能看不到。非常感谢你!如果你需要小费,请告诉我一个贝宝:)@顽皮液近乎完美!!!这不是我想要的;)我继续完善我的方法,同时尝试打破它,将其重写为一个可调用函数,包括一组完整的测试字符串和输出,解释了函数的限制,实现了为多个用户删除引号块的可能性。如果这不是绝对完美的,请让我知道如何,我会进一步发展它。我认为你的问题被否决了,因为它似乎没有得到充分的研究。我认为这将是有益的,所以你会看到它的投票结果是积极的。
/*
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=="[quote={$user}]"){ // 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,'[/quote]')!==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='[quote=testuser]
[quote=anotheruser]a sdasdsa dfv rdfgrgre gzdf vrdg[/quote]
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='[quote=mickmackusa]Keep this[/quote]
[quote=testuser]Don\'t keep this because
[quote=mickmackusa]said don\'t do it[/quote]
... like that\'s a good reason
[quote=NaughtySquid] It\'s tricky business, no?[/quote]
[quote=nester][quote=nesty][quote=nested][/quote][/quote][/quote]
[/quote]
Let\'s remove a second set of quotes
[quote=testuser]Another quote block[/quote]
[quote=mickmackusa]Let\'s do a third quote inside of my quote...
[quote=testuser]Another quote block[/quote]
[/quote]
This should be good, but
What if [quote=testuser]quotes himself [quote=testuser] inside of his own[/quote] quote[/quote]?';
/* output: [quote=mickmackusa]Keep this[/quote]
Let's remove a second set of quotes
[quote=mickmackusa]Let's do a third quote inside of my quote...
[/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 [quote=mickmackusa] has not end tag.';
/* output: This [quote=mickmackusa] has not end tag. */
/* Too few end quote tags by unwanted user: */
//$bbcode='This [quote=testuser] 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 [quote=testuser] has too many end[/quote] 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;
*/