如何解决搜索并替换PHP中给定模式内的字符串
我正在尝试从给定的字符串模式生成html,类似于插件。 有三种模式,一个 no arg,一个单 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}
我的目标是用某些东西替换那些“标签”(对于每个问题来说,处理这个问题并不重要)。但是我希望能够将给出的args传递给应该处理该逻辑的类/函数。
这是我的第一次尝试,不使用正则表达式,因为我不知道如何使用正则表达式(主要是因为它们速度较慢)。
<?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,$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沙箱中使用。
该代码似乎可以正常工作(暂时),但是似乎很粗略。您会以不同的方式处理这个问题吗?我可以以某种方式重构此代码吗?
解决方法
如果您选择使用基于正则表达式的字符串操作功能,为什么不使用const isReq = (string) => {
const matched = string.match(/^<(.+)>$/);
return matched ? matched[1] : false;
};
if (command.args) {
var everythingAccountedFor = false;
const options = command.args.split(' | ');
for (const option of options) {
const [definer,...values] = option.split(' ');
if (definer !== args[0]) continue;
if (
values.some((word,index) => isReq(word) && args[index + 1] !== isReq(word))
)
break;
everythingAccountedFor = true;
break;
}
if (!everythingAccountedFor)
return message.channel.send(
`You're message did not provide a required argument.\nHere is the command structure: \`${command.args}\``
);
}
将输入分解为有效部分呢?
这是另一种实现方式:
explode
当然,回声线可能会被丢弃。将它们放置到位后,我们得到以下输出:
function processPlugins($text,$pos = 0,$start = '{',$end = '}') {
$t = substr($text,$pos);
if($pos > 0) {
echo "$pos chracters removed from the begining: $t" . PHP_EOL;
} else {
echo "Starting with '$t'" . PHP_EOL;
}
$parts = explode($start,$t);
$t = $parts[1];
$parts = explode($end,$t);
$t = $parts[0];
echo "The part between curly braces: '$t'" . PHP_EOL;
$t = str_replace(['plugin1','plugin2'],'',$t);
echo "After plugin name has been removed: '$t'" . PHP_EOL;
$n = strlen($t);
if(!$n) {
echo "Processing complete: " . trim($parts[0]) . PHP_EOL . PHP_EOL;
return;
}
$params = explode('|',$t);
echo 'Key-Values: ' . json_encode($params) . PHP_EOL;
$kv = [];
foreach($params as $p) {
list($k,$v) = explode('=',trim($p));
echo " Item: '$p',Key: '$k',Value: '$v'" . PHP_EOL;
if($k === '') {
echo "Processing complete: $v" . PHP_EOL . PHP_EOL;
return;
}
$kv[$k] = $v;
}
echo "Processing complete: " . json_encode($kv) . PHP_EOL . PHP_EOL;
}
echo '<pre>';
processPlugins('{plugin1}');
processPlugins('{plugin2=3}');
processPlugins('{plugin2 arg1=b|arg2=d}');
,
此版本适用于具有多个插件令牌的输入。
function processPlugins($text,$end = '}') {
$processed = [];
$t = substr($text,$pos);
$parts = explode($start,$t);
array_shift($parts);
foreach($parts as $part) {
$pparts = explode($end,$part);
$t = trim($pparts[0]);
$t = str_replace(['plugin1',$t);
$n = strlen($t);
if(!$n) {
$processed[] = trim($pparts[0]);
continue;
}
$params = explode('|',$t);
$kv = [];
foreach($params as $p) {
list($k,trim($p));
if(trim($k) === '') {
$processed[] = trim($v);
continue 2;
}
$kv[trim($k)] = trim($v);
}
$processed[] = $kv;
}
return $processed;
}
function test($case) {
$p = processPlugins($case);
echo "$case => " . json_encode($p) . PHP_EOL;
}
$cases = [
'{plugin1}','{plugin2=3}','{plugin2 arg1=b|arg2=d}','text here {plugin1} and more{plugin2=55}here {plugin2 arg1=b|arg2=d} till the end'
];
foreach($cases as $case) {
test($case);
}
输出:
{plugin1} => ["plugin1"]
{plugin2=3} => ["3"]
{plugin2 arg1=b|arg2=d} => [{"arg1":"b","arg2":"d"}]
text here {plugin1} and more{plugin2=55}here {plugin2 arg1=b|arg2=d} till the end => ["plugin1","55",{"arg1":"b","arg2":"d"}]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。