在PHP中使用Bash大括号扩展?

3
有没有一种 PHP 的方法可以实现 bash 大括号扩展?例如:
[chiliNUT@server ~]$ echo {hello,hi,hey}\ {friends,world},
hello friends, hello world, hi friends, hi world, hey friends, hey world,

something like

<?php
echo brace_expand("{hello,hi,hey} {friends,world}");
//hello friends, hello world, hi friends, hi world, hey friends, hey world,

目前我正在使用

<?php
echo shell_exec("echo {hello,hi,hey}\ {friends,world}");

但这似乎不是正确的方法(并且可能在Windows服务器上无法工作)。
请注意,这仅适用于打印字符串的用例,而不涉及大括号扩展的其他功能,例如运行命令组相关的功能。

你可以使用嵌套循环,不是吗?我不知道有任何内置的PHP函数可以做到这一点。 - Charlotte Dunois
@CharlotteDunois 我考虑过嵌套循环,但似乎你需要事先知道大括号表达式的数量,而bash可以处理任意数量的大括号表达式。 - chiliNUT
仅仅是打印一段文本吗? - MoeinPorkamel
@MoeinPorkamel 对于我的使用情况,是的,绝对可以,只需打印一个字符串。 - chiliNUT
如果从性能角度来看是可以接受的,那么继续使用 shell_exec()。如果您想在循环中执行此任务,可以使用 popen 启动一个 shell,并重复使用已打开的 shell 执行每个扩展操作。 - hek2mgl
1个回答

1
这应该可以解决你的问题(你也可以改进它):
<?php

function brace_expand($string)
{
    preg_match_all("/\{(.*?)(\})/", $string, $Matches);

    if (!isset($Matches[1]) || !isset($Matches[1][0]) || !isset($Matches[1][1])) {
        return false;
    }

    $LeftSide = explode(',', $Matches[1][0]);
    $RightSide = explode(',', $Matches[1][1]);

    foreach ($LeftSide as $Left) {
        foreach ($RightSide as $Right) {
            printf("%s %s" . PHP_EOL, $Left, $Right);
        }
    }
}

brace_expand("{hello,hi,hey} {friends,world}");

输出:

hello friends
hello world
hi friends
hi world
hey friends
hey world

编辑:无限括号支持
<?php

function brace_expand($string)
{
    preg_match_all("/\{(.*?)(\})/", $string, $Matches);

    $Arrays = [];

    foreach ($Matches[1] as $Match) {
        $Arrays[] = explode(',', $Match);
    }

    return product($Arrays);
}

function product($a)
{
    $result = array(array());
    foreach ($a as $list) {
        $_tmp = array();
        foreach ($result as $result_item) {
            foreach ($list as $list_item) {
                $_tmp[] = array_merge($result_item, array($list_item));
            }
        }
        $result = $_tmp;
    }
    return $result;
}

print_r(brace_expand("{hello,hi,hey} {friends,world} {me, you, we} {lorem, ipsum, dorem}"));

1
这将处理恰好2个括号表达式,但不是任意数量的表达式。 - chiliNUT
1
这太棒了!不过它没有考虑大括号之间的字符(例如,{hello,hi} to my {friends,enemies} 应该输出 hello to my friends hello to my enemies hi to my friends hi to my enemies,但我认为我可以自己解决这个问题;这是一个很好的开始。 - chiliNUT

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