草庐IT

PHP发誓单词过滤器

coder 2024-01-01 原文

我正在开发一个WordPress插件,该插件用列表中的随机新单词替换评论中的不良单词。

我现在有2个数组:一个包含坏词,另一个包含好词。

$bad = array("bad", "words", "here");
$good = array("good", "words", "here");

因为我是初学者,所以我在某个时候陷入了困境。

为了替换坏词,我一直在使用$newstring = str_replace($bad, $good, $string);

我的第一个问题是我想关闭区分大小写的功能,因此我不会放置像"bad", "Bad", "BAD", "bAd", "BAd", etc这样的词,但是我需要新词来保留原始词的格式,例如,如果我写“Bad”,将被替换为“单词”,但是如果我输入“bad”,它将被替换为“words”,依此类推。

我的第一个难题是使用str_ireplace,但它忘记了原始单词是否带有大写字母。

第二个问题是我不知道如何处理这样的用户:“b a d”,“w o r d s”等。我需要一个主意。

为了使其选择一个随机词,我想我可以先使用$new = $good[rand(0, count($good)-1)];,再使用$newstring = str_replace($bad, $new, $string);。如果您有更好的主意,我在这里听。

我的脚本的总体外观:
function noswear($string)
{
    if ($string)
    {       
        $bad = array("bad", "words");
        $good = array("good", "words"); 
        $newstring = str_replace($bad, $good, $string);     
        return $newstring;
}

echo noswear("I see bad words coming!");

预先感谢您的帮助!

最佳答案

前体
通过实现此功能,您(和/或您的代码)存在(如在注释中多次指出的)空白,仅举几个例子:

人们会添加字符来愚弄过滤器

  • 人们将变得富有创造力(例如innuendo)
  • 人们会使用被动攻击和 mock
  • 人们将使用句子/短语,而不仅仅是单词

  • 您最好实现一个审核/举报系统,使人们可以举报令人反感的评论,然后由mods,用户等进行编辑/删除。
    基于这种理解,让我们继续...
    解决方案
    鉴于您:
  • 禁止使用单词列表$bad_words
  • 有一个替换单词列表$good_words
  • 不管大小写,想要替换坏词
  • 想要用随机的好词替换坏词
  • 具有正确转义的坏词列表:请参见http://php.net/preg_quote

  • 您可以非常容易地使用PHPpreg_replace_callback函数:
    $input_string = 'This Could be interesting but should it be? Perhaps this \'would\' work; or couldn\'t it?';
    
    $bad_words  = array('could', 'would', 'should');
    $good_words = array('might', 'will');
    
    function replace_words($matches){
        global $good_words;
        return $matches[1].$good_words[rand(0, count($good_words)-1)].$matches[3];
    }
    
    echo preg_replace_callback('/(^|\b|\s)('.implode('|', $bad_words).')(\b|\s|$)/i', 'replace_words', $input_string);
    
    好的,所以preg_replace_callback要做的是编译包含所有不良词的正则表达式模式。匹配将采用以下格式:
    /(START OR WORD_BOUNDARY OR WHITE_SPACE)(BAD_WORD)(WORD_BOUNDARY OR WHITE_SPACE OR END)/i
    
    i修饰符使其不区分大小写,因此badBad都将匹配。
    然后,函数replace_words接受匹配的单词及其边界(空白或空白字符),并用边界和一个随机的好单词替换它。
    global $good_words; <-- Makes the $good_words variable accessible from within the function
    $matches[1] <-- The word boundary before the matched word
    $matches[3] <-- The word boundary after  the matched word
    $good_words[rand(0, count($good_words)-1] <-- Selects a random good word from $good_words
    
    匿名功能
    您可以使用preg_replace_callback中的匿名函数将以上内容重写为一个内衬
    echo preg_replace_callback(
            '/(^|\b|\s)('.implode('|', $bad_words).')(\b|\s|$)/i',
            function ($matches) use ($good_words){
                return $matches[1].$good_words[rand(0, count($good_words)-1)].$matches[3];
            },
            $input_string
        );
    
    功能包装
    如果您打算多次使用它,您也可以将其编写为自包含函数,尽管在这种情况下,您最有可能希望在调用函数时将好/坏词输入到函数中(或在其中永久性地对其进行硬编码),但这取决于您如何导出它们...
    function clean_string($input_string, $bad_words, $good_words){
        return preg_replace_callback(
            '/(^|\b|\s)('.implode('|', $bad_words).')(\b|\s|$)/i',
            function ($matches) use ($good_words){
                return $matches[1].$good_words[rand(0, count($good_words)-1)].$matches[3];
            },
            $input_string
        );
    }
    
    echo clean_string($input_string, $bad_words, $good_words);
    
    输出
    使用第一个示例中显示的输入和单词列表连续运行以上功能:
    This will be interesting but might it be? Perhaps this 'will' work; or couldn't it?
    This might be interesting but might it be? Perhaps this 'might' work; or couldn't it?
    This might be interesting but will it be? Perhaps this 'will' work; or couldn't it?
    
    当然,替换词是随机选择的,因此,如果刷新页面,我还会得到其他内容。。。但这表示什么/没有被替换。
    N.B.
    转义$bad_words
    foreach($bad_words as $key=>$word){
        $bad_words[$key] = preg_quote($word);
    }
    
    字边界\b在此代码中,我使用了\b\s^$作为单词边界,这是有充分理由的。尽管white spacestart of stringend of string都被视为单词边界\b在所有情况下均不匹配,例如:
    \b\$h1t\b <---Will not match
    
    这是因为\b与非单词字符(即[^a-zA-Z0-9])匹配,并且像$这样的字符不算作单词字符。
    杂项
    根据单词列表的大小,可能会出现一些潜在的问题。从系统设计的角度来看,拥有大量正则表达式通常是不好的形式,其原因有两个:
  • 很难维护
  • 很难读懂它的作用
  • 很难找到错误
  • 如果列表太大,可能会占用大量内存。

  • 鉴于正则表达式模式是由PHP编译的,因此第一个原因被否定了。第二个也应该被否定;如果您的单词列表很大,每个不好的单词都有很多排列,那么我建议您停止并重新考虑您的方法(阅读:使用标记/审核系统)。
    需要澄清的是,我看不出有一个小的单词列表可以过滤掉特定的词汇,因为它的目的是:阻止用户彼此爆发;当您尝试过滤掉过多的(包括排列)时,就会出现问题。坚持过滤常见的脏话,如果这不起作用,那么-最后一次-实现标记/审核系统。

    关于PHP发誓单词过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19358774/

    有关PHP发誓单词过滤器的更多相关文章

    1. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

      我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

    2. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

      是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

    3. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

      @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

    4. Python 刷Leetcode题库,顺带学英语单词(31) - 2

      ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem

    5. ruby-on-rails - 在 Controller 中干净地处理多个过滤器(参数) - 2

      我有一个名为Post的类,我需要能够适应以下场景:如果用户选择了一个类别,则只显示该类别的帖子如果用户选择了一种类型,则只显示该类型的帖子如果用户选择了一个类别和类型,则只显示该类别中该类型的帖子如果用户没有选择任何内容,则显示所有帖子我想知道我的Controller是否不可避免地会因大量条件语句而显得粗糙...这是我解决此问题的错误方法-有谁知道我如何才能做到这一点?classPostsController 最佳答案 您最好遵循“胖模型,瘦Controller”的惯例,这意味着您应该将这种逻辑放在模型本身中。Post类应该能够报告

    6. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

      我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

    7. ruby-on-rails - Rails 3 - 过滤器链暂停为 :authentication rendered or redirected - 2

      我仍然收到标题中的“错误”消息,但不知道如何解决。在ApplicationController中,classApplicationController在routes.rb#match'set_activity_account/:id/:value'=>'users#account_activity',:as=>:set_activity_account--thisdoesn'tworkaswell..resources:usersdomemberdoget:action_a,:action_bendcollectiondoget'account_activity'endend和User

    8. ruby-on-rails - ActiveAdmin 自定义选择过滤器下拉名称 - 2

      对于用户模型,我有一个过滤器来检查用户的预订状态,该状态由整数值(0、1或2)表示。UserActiveAdmin索引页上的过滤器是通过以下代码实现的:filter:booking_status,as::select然而,这会导致下拉选项为0、1或2。当管理员用户从下拉列表中选择它们时,我更愿意自己将它们命名为“未完成”、“待定”和“已确认”之类的名称。有没有办法在不改变booking_status在模型中的表示方式的情况下做到这一点? 最佳答案 假设booking_status是模型中的枚举字段,您可以使用:过滤器:booking

    9. ruby - 如何在 Cucumber 步骤定义中使单词可选? - 2

      我在下面有一个步骤定义,它执行我想要它执行的操作,即它根据“PAGES”哈希的“page”元素检查页面的url。Then(/^Ishould(still)?beatthe"(.*)"page$/)do|still,page|BROWSER.url.should==PAGES[page]end步骤定义用于两者我应该在...页面我应该还在...页面但是,我不需要将“still”传递到block中。我只需要它是可选的以匹配步骤但不传递到block中。我该怎么做?谢谢。 最佳答案 您想将“静止”组标记为非捕获。这是通过使用?:启动组来完成的

    10. ruby - 如何对 ruby​​ 中的重音单词数组进行排序 - 2

      如何根据变量alpha的每个字母对重音单词数组进行排序。下面的代码只引用了第一个字母的alpha,所以我无法获得“ĝusti”、“ĝustivin”、“ĝuspa”到正确排序。我需要这样的代码来对单词进行排序:["bonanmatenon","ĉuviparolasesperanton","ĝuspa","ĝusti","ĝustivin","miamasvin","pacon"]defalphabetize(phrases)alpha="abcĉdefgĝhĥijĵklmnoprsŝtuŭvz".split(//)phrases.sort_by{|phrase|alpha.index

    随机推荐