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

发表回复