我有以下代码:
<?php
$subject = "Replace ? question mark in brackets [? with ? incremental ??]? digits";
echo incremental_replace($subject);
// i want the folowing:
// Replace ? question mark in brackets [1 with 2 incremental 34]? digits
我希望替换括号中的所有?
。此外,?
的数量和位置可能会发生变化。
我如何用PHP做到这一点?我认为这可以用preg_replace完成,但我不知道如何。
答案 0 :(得分:3)
如果括号没有嵌套,那么以下就足够了
echo preg_replace('~\?(?=[^\[\]]*\])~e', '++$n', $subject);
否则使用解析器:
$subject = "Replace ? question mark in [nested ? brackets] [? with ? [incremental ? [?]] ??]? digits";
$result = '';
$bc = $n = 0;
foreach(str_split($subject) as $c) {
if($c == '[') $bc++;
if($c == ']') $bc--;
if($c == '?' && $bc) $c = ++$n;
$result .= $c;
}
echo $result;
嵌套括号的正则表达式是可能的,但是会太长并且搞砸了。
OP注意:如果替换不是增量数字而是数组,您可以执行以下操作:
$n = 0;
$rep = array('foo', 'bar', 'baz', 'qux', 'quux');
echo preg_replace('~\?(?=[^\[\]]*\])~e', '$rep[$n++]', $subject);
答案 1 :(得分:2)
function incremental_replace($subject) {
$replacer = function($matches) {
$index = 0;
return preg_replace('/\?/e', '++$index', $matches[0]);
};
return preg_replace_callback('/\[[^\]]*\]/', $replacer, $subject);
}
$subject = "Replace ? question mark in brackets [? with ? incre?mental ??]?...";
echo incremental_replace($subject);
我误解了这个问题,并回答了另一个类似的问题。我在这里留下答案,因为有人可能觉得它很有用。
一般的想法是:
function replacer($matches) {
$replacements = array(1, 2, 34);
$index = 0;
return preg_replace('/\?+/e', '$replacements[$index++]', $matches[0]);
}
$subject = "Replace ? question mark in brackets [? with ? incremental ??]?...";
echo preg_replace_callback('/\[[^\]]*\]/', 'replacer', $subject);
<强> See the basic concept in action 强>
如果你使用PHP&gt; = 5.3,那么你可以做一个更通用的解决方案:
function incremental_replace($subject, $replacements) {
$replacer = function($matches) use ($replacements) {
$index = 0;
return preg_replace('/\?+/e', '$replacements[$index++]', $matches[0]);
};
return preg_replace_callback('/\[[^\]]*\]/', $replacer, $subject);
}
$subject = "Replace ? question mark in brackets [? with ? incremental ??]?...";
echo incremental_replace($subject, array(1, 2, 34));
最后,如果您愿意将自己限制在仅限单个问号(即如果括号内的??
可以更改为?
),那么您可以将“替换器”功能中的preg_replace
与简单的str_replace
交换,这样会更快。
答案 2 :(得分:1)
一个简单的解析器可以完成这项工作。这只是一个简单的解决方案,有改进的余地。但在这种情况下,preg_replace()
或preg_replace_callback()
可能更有效。
function incremental_replace($subject) {
$inBracket = 0;
$length = strlen($subject);
$count = 0;
$result = '';
for ($i = 0; $i < $length; $i++) {
$char = $subject[$i];
switch ($char) {
case '[':
$inBracket++;
break;
case ']':
$inBracket--;
break;
case '?':
if ($inBracket > 0) {
$char = ++$count;
}
break;
}
$result .= $char;
}
return $result;
}
$subject = "Replace ? question mark in brackets [? with ? incremental ??]? digits";
echo incremental_replace($subject);
// Replace ? question mark in brackets [1 with 2 incremental 34]? digits
答案 3 :(得分:1)
function replaceThem($matches){
$i = 1;
while ($pos = strpos($matches[0], '?'))
$matches[0][$pos] = $i++;
return $matches[0];
}
$subject = "Replace ? question mark in brackets [? with ? incremental ??]? digits";
echo preg_replace_callback('/\[[^\]]+\]/', 'replaceThem', $subject);
答案 4 :(得分:0)
也许最好循环遍历字符串的字符。如果您通过开口支架,请将您遇到的问号替换为计数器,同样替换第二个等问题,如果您通过了关闭支架......请停止更换。