Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/252.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何从文本中删除特定用户的所有bbcode引号块?_Php_Regex_Substring_Filtering_Bbcode - Fatal编程技术网

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”被阻止,他们不希望整个引用部分,包括嵌套在其中的第二个引用,因为这是主引用的一部分 因此,该职

我希望删除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\]/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;
    */