代码之家  ›  专栏  ›  技术社区  ›  Andres SK

PHP:在坏词模糊器中使用特殊字符

  •  1
  • Andres SK  · 技术社区  · 7 年前

    它工作得很好,除非我在西班牙语中使用包含特殊字符的单词,例如:±, , 等。

    这是我当前的代码:

    <?    
    function badwords_full($string, &$bad_references) {
        static $bad_counter;
        static $bad_list;
        static $bad_list_q;
        if(!isset($bad_counter)) {
            $bad_counter = 0;
            $bad_list = badwords_list();
            $bad_list_q = array_map('preg_quote', $bad_list);
        }
        return preg_replace_callback('~('.implode('|', $bad_list_q).')~',
            function($matches) use (&$bad_counter, &$bad_references) {
                $bad_counter++;
                $bad_references[$bad_counter] = $matches[0];
                return substr($matches[0], 0, 1).str_repeat('&squf;', strlen($matches[0]) - 1);
        }, $string);
    }
    
    function badwords_list() {
        # spanish
        $es = array(
            "gallina",
            "ñoño"
        );
    
        # english
        $en = array(
            "chicken",
            "horse"
        );
    
        # join all languages
        $list = array_merge($es, $en);
        usort($list, function($a,$b) {
            return strlen($b) < strlen($b);
        });
        return $list;
    }
    
    $bad = []; //holder for bad words
    

    测试1:

    echo badwords_full('Hello, you are a chicken!', $bad);
    

    你好,你是c(工作正常)

    echo badwords_full('Hola en español eres un ñoño!', $bad);
    

    结果2:

    你好±欧莱森!

    关于如何解决这个问题有什么想法吗?谢谢!

    1 回复  |  直到 7 年前
        1
  •  3
  •   user3783243    7 年前

    您正在将多字节字符一分为二。使用 mb_substr 代替 substr

    return mb_substr($matches[0], 0, 1).str_repeat('&squf;', strlen($matches[0]) - 1);
    

    https://3v4l.org/AnPJl

    你可能也想用 mb_strlen strlen .