正则表达式将abcd转换为(a(b(c(d))))。

3

我正在使用PHP的 preg_replace 函数,尝试将字符串

abcd

转换为

(a(b(c(d))))

以下是我能够得到的最佳结果:

preg_replace('/.(?=(.*$))/', '$0($1)', 'abcd');
// a(bcd)b(cd)c(d)d()

使用正则表达式可以实现吗?

编辑:我刚刚在 PCRE 规范中发现了这个问题:替换不受重新匹配的影响,因此我的原始方法行不通。 我想保持所有的正则表达式,因为在我的实际用例中有一些更复杂的匹配逻辑。


回复:“我想全部使用正则表达式,因为我的实际用例中有一些更复杂的匹配逻辑”:您能否用示例输入和输出描述您的实际用例以及/或更复杂的匹配逻辑? - ruakh
1
你没有给别人足够的时间来尝试回答这个问题。 - DiverseAndRemote.com
4个回答

6
如何:
preg_replace('/./s', '($0', 'abcd') . str_repeat(')', strlen('abcd'));

这算不算“使用正则表达式”?


1

您可以使用 preg_match_all。不过我不确定您需要哪种字符,所以我将为所有字符提供一个示例:

$val = 'abcd1234';
$out = '';

if(preg_match_all('#.#', $val, $matches))
{
    $i = 0; // we'll use this to keep track of how many open paranthesis' we have
    foreach($matches[0] as &$v)
    {
        $out .= '('.$v;
        $i++;
    }
    $out .= str_repeat(")", $i);
}
else
{
    // no matches found or error occured
}

echo $out; // (a(b(c(d(1(2(3(4))))))))

这也很容易进一步定制。


当我想要进行大量字符串处理时,我总是会使用preg_match_all。试图将大量字符串处理放入一个preg_replace中就像一次性把所有购物从车里拿出来一样。一次拿一两个袋子就足够了。 - Deji
在我看来,这更符合自然。我的意思是,即使没有它,$v仍将保留对数组索引的引用,但在PHP中并非总是如此,在C中也从未如此,这是我习惯的力量。所以,我猜是出于习惯。不过,我知道如果改变它,我就改变了数组;如果不改变,那么结果没有区别。 - Deji
没有 &,$v 将不会被引用为数组值(在哪些例子中是正确的?)。 - Glavić
我并没有说它不会是一个数组值引用。我说的是“即使没有它,$v仍然会保持对数组索引的引用,但在PHP中并不总是这样”。我并不是指foreach有任何例外,但$array2 = $array仍然会复制数组,这就是为什么我觉得每当我想要指定变量确实是指针而不是新值时,使用&更自然。如果PHP再次从头设计,我相信这将成为标准,因为&有时是必要的,有时不是,这对于编程语言来说有点模糊。 - Deji
好的,我明白。但是,如果您这样做,那么请至少在foreach结束时使用unset($v);。否则,在foreach之后使用变量$v = '123';时,很快就会出现错误,并且这将更新数组中的最后一条记录。 - Glavić

0

这是我的做法 =) :

<?php
$arr = str_split("abcd");
$new_arr =  array_reverse($arr);

foreach ($new_arr as $a) {
    $str = sprintf('(%s%s)', $a, $str);
}
echo "$str\n";

?>

KISS 不是吗?(几行:6)


0

我选择了以上答案的组合:

preg_match_all('/./ui', 'abcd', $matches);
$matches = $matches[0];
$string = '('.implode('(', $matches).str_repeat(')', count($matches));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,