[英]Search and replace a string within a given pattern in PHP
我正在尝试从给定的字符串模式生成 html,类似于插件。 共有三种模式,无arg、单arg 和多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, $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 沙箱中工作。
这段代码似乎工作(目前),但它似乎粗略。 你会以不同的方式处理这个问题吗? 我可以以某种方式重构这段代码吗?
如果您选择字符串操作函数而不是正则表达式,为什么不使用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}');
当然,回声线可以扔掉。 有了它们,我们得到了这个输出:
Starting with '{plugin1}'
The part between curly braces: 'plugin1'
After plugin name has been removed: ''
Processing complete: plugin1
Starting with '{plugin2=3}'
The part between curly braces: 'plugin2=3'
After plugin name has been removed: '=3'
Key-Values: ["=3"]
Item: '=3', Key: '', Value: '3'
Processing complete: 3
Starting with '{plugin2 arg1=b|arg2=d}'
The part between curly braces: 'plugin2 arg1=b|arg2=d'
After plugin name has been removed: 'arg1=b|arg2=d'
Key-Values: [" arg1=b","arg2=d"]
Item: ' arg1=b', Key: 'arg1', Value: 'b'
Item: 'arg2=d', Key: 'arg2', Value: 'd'
Processing complete: {"arg1":"b","arg2":"d"}
此版本适用于具有多个插件令牌的输入。
function processPlugins($text, $pos = 0, $start = '{', $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', 'plugin2'], '', $t);
$n = strlen($t);
if(!$n) {
$processed[] = trim($pparts[0]);
continue;
}
$params = explode('|', $t);
$kv = [];
foreach($params as $p) {
list($k, $v) = explode('=', 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"}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.