这个工具类可以帮助大家,在PHP上去运行QR的词库,将QR词库执行后转换为PHP可读的字符串,此工具类原理解释我发到B站了,大家可以去B站看看。
https://www.bilibili.com/video/bv1BV4y177q6
代码解释就不做了吧,已经在B站视频一行一行讲了。
<?php
/**
 * 哔哩哔哩:萌新杰少 - 2022-7-19
 * 半成品 仅仅支持了 读写和DIC普通内容 变量创建,替换也完成了,剩下的就是拓展功能,自行发挥。
 * 没有写构造方法自己补全一下,以便使用,dicRun示范了用户消息和词库内容
 * 更具dicRun示范试试看
 * 开源协议/君子协议 GPL-3.0 license 
 * 此类全程使用原生函数,没有导入其他包,可放心维护食用。
 * 功能大概是把QR词库直接放进来,会转换成最终输出内容。
 */
class QrDicUtils
{
    public $message = "";
    public $valueArray = [];
    public $matches = "";
    public $userMessage = "你好 文档"; //用户信息
    public $ifState;
    public $ifType = false;
    public $ifEndState = false;
    public function dicRun()
    {
        /**
         * 词库示范
         * 
         * 你好
         * B:123213213
         * $写 data/cs.txt a %B%$
         * A:$读 data/cs.txt a 0$
         * 如果:1==1
         * adaw
         * 返回
         * 如果尾
         * 213213
         * %A%
         * 
         */
        //初始化配置
        $user_message = "你好 21321"; //用户
        $handle = fopen('dic.txt', 'r'); //词库信息
        //语法处理状态
        $handleState = false;
        //终止检测
        $readState = true;
        //满足全部条件则进行 逐行读取
        while (false !== ($dic = fgets($handle, 1024)) && $readState != false) {
            //去掉空格 继承用户的空格 转义$避免正则出错
            $dic = str_replace(PHP_EOL, '', $dic);
            $dic = str_replace("$", "\$", $dic);
            //命令匹配状态检验
            if ($handleState) {
                //去掉
                if (preg_replace('/\s+/', '', $dic != "")) {
                    //并非命令内容读取结束 因为这一行还是有内容的,参照QRDIC的写法,不需要自行换行,直接拼接内容。
                    $this->message = $this->message . self::messageHandle($dic);
                } else {
                    //此命令已经达到最后一行,关闭读取
                    $readState = false;
                    //恢复命令检测
                    $handleState = false;
                    $this->ifState = false;
                    $this->ifType = false;
                    $this->ifEndState = false;
                }
            } else {
                //没有检测到之前遍历检测
                $dic = str_replace("/", "\/", $dic);
                if (preg_match("/^" . trim($dic) . "$/", $user_message, $this->matches)) {
                    $handleState = true;
                }
            }
        }
        //关闭词库
        fclose($handle);
        //回答内容
        return $this->message;
    }
    //写入 
    public function writeFile($path, $tag, $content)
    {
        $pathEp = explode("/", $path);
        $name = $pathEp[(sizeof($pathEp) - 1)];
        $path = str_replace($name, '', $path);
        $return = false;
        $content = str_replace("\n", '\\n', $content);
        //判断文件是否存在
        if (file_exists($path . $name)) {
            $mFile = fopen($path . $name, "w+");
            $return = fwrite($mFile, $tag . "=" . $content);
            fclose($mFile);
        } else {
            if (!is_dir($path)) {
                //创建文件夹
                if(substr(php_uname("s"),0,3) == "Win") $path = iconv("UTF-8", "GBK", $path);
                mkdir($path, 0777, true);
            }
            $mFile = fopen($path . $name, "w+");
            $return = fwrite($mFile, $tag . "=" . $content);
            fclose($mFile);
        }
        return $return;
    }
    //读取
    public function readMyFile($path, $tag)
    {
        $pathEp = explode("/", $path);
        
        $name = $pathEp[(sizeof($pathEp) - 1)];
        $path = str_replace($name, '', $path);
        $return = false;
        //判断文件是否存在
        if (file_exists($path . $name)) {
            $mFile = fopen($path . $name, "a+");
            $return = fread($mFile, filesize($path . $name));
            preg_match('/' . $tag . '=(.*)/', $return, $matches);
            $return = $matches[1];
            fclose($mFile);
        } else {
            if (!is_dir($path)) {
                //创建文件夹
                if(substr(php_uname("s"),0,3) == "Win") $path = iconv("UTF-8", "GBK", $path);
                mkdir($path, 0777, true);
            }
            $mFile = fopen($path . $name, "w+");
            fwrite($mFile, $tag . "=0");
            $mFile = fopen($path . $name, "a+");
            $return = fread($mFile, filesize($path . $name));
            preg_match('/' . $tag . '=(.*)/', $return, $matches);
            $return = $matches[1];
            fclose($mFile);
        }
        return $return;
    }
    //消息处理方法 匹配到了就是message 否则输出 dic
    public function messageHandle($dic)
    {
        //内部消息初始化
        $message = "";
 
        //状态判断
        if ($dic == "返回" || $dic == "如果尾") {
            $this->ifEndState = true;
            return $message;
        }
        //判断语句 得在如果语法成立后之前进行 否则嵌套如果将出现问题
        if (preg_match('/^如果:(.*)$/', $dic, $matches)) {
            //初始化内容
            $this->ifState = false;
            $this->ifType = false;
            $this->ifEndState = false;
            if (self::calculation($matches[1])) {
                $this->ifType = 1;
                $this->ifState = true;
            } else {
                $this->ifType = 0;
                $this->ifState = true;
            }
            return $message;
        }
        if ($this->ifState) {
            if ($this->ifType == 0) {
                if (!$this->ifEndState) {
                    return $message;
                }
            } else {
                if ($this->ifEndState) {
                    return $message;
                }
            }
        }
        //变量生成
        if (preg_match('/^(.?):(\S.*)/', $dic, $matches)) {
            $this->valueArray[$matches[1]]['value'] = self::messageHandle($matches[2]);
            return $message;
        }
        //变量替换 -> 可能是多个 采用 preg_match_all
        if (preg_match_all('/%(.*?)%/', $dic, $matches)) {
            //逐一替换
            for ($i = 0; $i < sizeof((array)$matches[1]); $i++) {
                if (preg_match('/^括号([0-9])$/', $matches[1][$i], $childMatches)) {
                    $dic = str_replace("%括号" . $childMatches[1] . "%", $this->matches[$childMatches[1]], $dic);
                }  else {
                    $dic = str_replace("%" . $matches[1][$i] . "%", $this->valueArray[$matches[1][$i]]['value'], $dic);
                }
            }
            //非最终不输出
        }
        //读判断
        if (preg_match('/\$读 (\S+) (\S+) (\S+)\$/', $dic, $matches)) {
            //$dic = str_replace("%" . $valueArray[$matches[1]]['value'] . "%", '', $dic);
            if (!$matches[3]) {
                $message = self::readMyFile($matches[1], $matches[2]);
            } else {
                $message = $message . $matches[3];
            }
            return $message;
        }
        //写判断
        if (preg_match('/\$写 (\S+) (\S+) (\S+)\$/', $dic, $matches)) {
            self::writeFile($matches[1], $matches[2], $matches[3]);
            return $message;
        }
        return $dic;
    }
    public function calculation($formula)
    {
        //相等判断
        if (preg_match('/^(.*)==(.*)$/', $formula, $matches)) {
            return self::messageHandle($matches[1]) == self::messageHandle($matches[2]);
        }
        if (preg_match('/^(.*)!=(.*)$/', $formula, $matches)) {
            return self::messageHandle($matches[1]) != self::messageHandle($matches[2]);
        }
        if (preg_match('/^(\d+)>(\d+)$/', $formula, $matches)) {
            return self::messageHandle($matches[1]) > self::messageHandle($matches[2]);
        }
        if (preg_match('/^(\d+)<(\d+)$/', $formula, $matches)) {
            return self::messageHandle($matches[1]) < self::messageHandle($matches[2]);
        }
        if (preg_match('/^(\d+)>=(\d+)$/', $formula, $matches)) {
            return self::messageHandle($matches[1]) >= self::messageHandle($matches[2]);
        }
        if (preg_match('/^(\d+)<=(\d+)$/', $formula, $matches)) {
            return self::messageHandle($matches[1]) <= self::messageHandle($matches[2]);
        }
    }
}
//实例化
$qrDicUtils = new QrDicUtils();
echo $qrDicUtils->dicRun();
                
发表回复