【发布时间】:2020-12-25 08:22:08
【问题描述】:
我正在尝试从给定的字符串模式生成 html,类似于插件。 共有三种模式,一个 no arg,一个 single arg 和一个 multi arg 字符串模式。我无法更改此模式,因为它来自 CMS。
{pluginName} or {pluginName=3} or {pluginName id=3|view=simple|arg999=asv}
一个例子:
<p>Hi this is a html page</p>
<p>The following line should generate html</p>
{pluginName=3}
<p>The following line also should generate html</p>
{pluginName id=3|view=simple|arg999=asv}
我的目标是用某些东西替换那些“标签”(对于这个问题,每个处理都说不相关)。但是,我希望能够将给定的参数传递给应该处理该逻辑的类/函数。
这是我的第一次尝试,没有使用正则表达式,因为我不知道如何用它们来解决这个问题(主要是因为它们速度较慢)。
<?php
function processPlugins($text, $pos = 0, $start = '{', $end = '}') {
$plugins = array('plugin1', 'plugin2');
while(($pos = strpos($text, $start, $pos)) !== false) {
$startPos = $pos;
$pos += strlen($start);
foreach($plugins as $plugin) {
if(substr($text, $pos, strlen($plugin)) === $plugin
&& ($endPos = strpos($text, $end, $pos + strlen($plugin))) !== false) {
$char = substr($text, $pos + strlen($plugin), 1); // 1 is strlen of (= or ' ')
$pos += strlen($plugin) + 1; // 1 is strlen of (= or ' ')
$argString = substr($text, $pos, $endPos - $pos);
if($char === ' ') { //Multi arg
$params = explode('|', trim($argString));
$paramDict = array();
foreach ($params as $param) {
list($k, $v) = array_pad(explode('=', $param), 2, null);
$paramDict[$k] = $v;
}
//$output = $plugin->processDictionary($paramDict);
var_dump($paramDict);
} elseif ($char === '=') { //One arg
//$output = $plugin->processArg($argString);
echo $argString . "\n";
} elseif ($char === $end) { //No arg
//$output = $plugin->processNoArg();
echo $plugin. "\n";
}
$pos = $endPos + strlen($end);
break;
}
}
}
}
processPlugins('{plugin1}');
processPlugins('{plugin2=3}');
processPlugins('{plugin2 arg1=b|arg2=d}');
前面的代码在 PHP 沙箱中工作。
这段代码似乎可以工作(目前),但看起来很粗略。你会以不同的方式处理这个问题吗?我可以以某种方式重构这段代码吗?
【问题讨论】: