这个工具类可以帮助大家,在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();
发表回复