Heim > Backend-Entwicklung > PHP-Tutorial > PHP implementiert illegale Wortfilterung (Algorithmusanalyse)

PHP implementiert illegale Wortfilterung (Algorithmusanalyse)

藏色散人
Freigeben: 2023-04-11 08:04:02
nach vorne
3225 Leute haben es durchsucht

Einführung in den Algorithmus 键 Bewirkt, dass ein Schlüsselwort einen Baum verursacht, und jedes Wort ist ein Knoten. Durchsuchen Sie die Aussagen, die gefiltert werden müssen, und durchsuchen Sie jedes Wort der Aussage im Baum, um festzustellen, ob es vorhanden ist.

Schwierigkeiten bei der Implementierung

Der Aufbau eines Baums ist einfach. Der entscheidende Punkt ist, dass Sie beim Durchlaufen einer Zeichenfolge in php die Länge eines einzelnen Zeichens korrekt ermitteln müssen.
Die Methode zum einfachen Durchlaufen einer Zeichenfolge ist wie folgt:
$strLen = mb_strlen($str);
for ($i = 0; $i < $strLen; $i++) {
    echo mb_substr($str, $i, 1, "utf8"),PHP_EOL;
}
Nach dem Login kopieren
Diese Methode verwendet die Funktionsreihe mb_*, um jedes Zeichen korrekt abzufangen. Die Geschwindigkeit ist sehr langsam, wenn eine große Zahl verarbeitet wird Meine Vermutung ist: mb_substrJedes Mal, wenn ein Zeichen abgefangen wird, muss die Anzahl der Zeichen vor der Zeichenfolge berechnet werden.
Der richtige Weg, einen String zu durchlaufen, besteht darin, den String gemäß den Codierungsregeln von utf8 abzufangen. Weitere Informationen finden Sie unten.

php中遍历字符串需要自己正确的得到单个字符的长度。
简单遍历字符串的方法如下:

<?php
/**
 * 非法关键词检查
 */
class SensitiveWords
{
    protected $tree = null;
    protected $callIsNumeric = true;
    /**
     * 非法词汇列表,一个非法词汇占用一行
     */
    public function __construct($path = __DIR__ . &#39;/sensitiveWords.txt&#39;)
    {
        $this->tree = new WordNode();
        $file = fopen($path, "r");
        while (!feof($file)) {
            $words = trim(fgets($file));
            if ($words == &#39;&#39;) {
                continue;
            }
            //存在纯数字的非法词汇
            if (is_numeric($words)) {
                $this->callIsNumeric = false;
            }
            $this->setTree($words);
        }
        fclose($file);
    }

    protected function setTree($words)
    {
        $array = $this->strToArr($words);
        $tree = $this->tree;
        $l = count($array) - 1;
        foreach ($array as $k => $item) {
            $tree = $tree->getChildAlways($item);
            if ($l == $k) {
                $tree->end = true;
            }
        }
    }

    /**
     * 返回包含的非法词汇
     * @param string $str
     * @return array
     */
    public function check($str)
    {
        //先压缩字符串
        $str = trim(str_replace([&#39; &#39;, "\n", "\r"], [&#39;&#39;, &#39;&#39;, &#39;&#39;], $str));
        $ret = [];
        loop:
        $strLen = strlen($str);
        if ($strLen === 0) {
            return array_unique($ret);
        }
        //非法词汇中没有纯数字的非法词汇,待检测字符串又是纯数字的,则跳过不再检查
        if ($this->callIsNumeric && is_numeric($str)) {
            return array_unique($ret);
        }
        //挨个字符进行判断
        $tree = $this->tree;
        $words = &#39;&#39;;
        for ($i = 0; $i < $strLen; $i++) {
            //unicode范围 --> ord 范围
            //一字节 0-127 --> 0 - 127
            //二字节 128-2047 --> 194 - 223
            //三字节 2048-65535 --> 224 - 239
            //四字节 65536-1114111 --> 240 - 244
            //@see http://shouce.jb51.net/gopl-zh/ch3/ch3-05.html
            $ord = ord($str[$i]);
            if ($ord <= 127) {
                $word = $str[$i];
            } elseif ($ord <= 223) {
                $word = $str[$i] . $str[$i + 1];
                $i += 1;
            } elseif ($ord <= 239) {
                $word = $str[$i] . $str[$i + 1] . $str[$i + 2];
                $i += 2;
            } elseif ($ord <= 244) {
                //四字节
                $word = $str[$i] . $str[$i + 1] . $str[$i + 2] . $str[$i + 3];
                $i += 3;
            } else {
                //五字节php都溢出了
                //Parse error: Invalid UTF-8 codepoint escape sequence: Codepoint too large
                continue;
            }
            //判断当前字符
            $tree = $tree->getChild($word);
            if (is_null($tree)) {
                //当前字不存在,则截取后再次循环
                $str = substr($str, $i + 1);
                goto loop;
            } else {
                $words .= $word;
                if ($tree->end) {
                    $ret[] = $words;
                }
            }
        }
        return array_unique($ret);
    }

    protected function strToArr($str)
    {
        $array = [];
        $strLen = mb_strlen($str);
        for ($i = 0; $i < $strLen; $i++) {
            $array[] = mb_substr($str, $i, 1, "utf8");
        }
        return $array;
    }
}
/**
 * 单个字符的节点
 */
class WordNode
{
    //是否为非法词汇末级节点
    public $end = false;
    //子节点
    protected $child = [];

    /**
     * @param string $word
     * @return WordNode
     */
    public function getChildAlways($word)
    {
        if (!isset($this->child[$word])) {
            $this->child[$word] = new self();
        }
        return $this->child[$word];
    }

    /**
     * @param string $word
     * @return WordNode|null
     */
    public function getChild($word)
    {
        if ($word === &#39;&#39;) {
            return null;
        }
        if (isset($this->child[$word])) {
            return $this->child[$word];
        }
        return null;
    }
}
Nach dem Login kopieren

该方法是利用mb_*系列函数来正确截取每个字符,处理大量字符串时速度非常慢,我猜测是:mb_substr每截取一个字符,都要计算该字符串之前,有多少个字符。
正确的遍历字符串的方式是按utf8

Algorithmus-Implementierung

rrreeeEmpfohlenes Lernen: „PHP-Video-Tutorial

Das obige ist der detaillierte Inhalt vonPHP implementiert illegale Wortfilterung (Algorithmusanalyse). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
php
Quelle:learnku.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage