php - 使用正则表达式的深度(无限)嵌套拆分词

标签 php arrays regex split explode

重要编辑:由于很多人都说应该避免这种情况并且几乎无法使用 RegEx,所以我将允许您使用其他一些解决方案。从现在开始,任何解决方案都可以作为答案,最终成为解决方案。谢谢!

假设我有:

$line = "{ It is { raining { and streets are wet } | snowing { and streets are { slippy | white }}}. Tomorrow will be nice { weather | walk }. }" 

期望的输出:

It is raining and streets are wet. Tomorrow will be nice weather.
It is raining and streets are wet. Tomorrow will be nice walk.
It is snowing and streets are slippy. Tomorrow will be nice weather.
It is snowing and streets are slippy. Tomorrow will be nice walk.
It is snowing and streets are white. Tomorrow will be nice weather.
It is snowing and streets are white. Tomorrow will be nice walk. 

使用 this answer 中的代码对于我之前的问题,我目前可以拆分单词但无法计算出嵌套值。有人能帮我解决我的问题吗?我很确定我应该在某处实现一个 for 循环以使其工作,但我不明白在哪里。

$line = "{This is my {sentence|statement} I {wrote|typed} on a {hot|cold} {day|night}.}";
 $matches = getMatches($line);
 printWords([], $matches, $line);


function getMatches(&$line) {
    $line = trim($line, '{}'); 
    $matches = null;
    $pattern = '/\{[^}]+\}/';

    preg_match_all($pattern, $line, $matches);

    $matches = $matches[0];

    $line = preg_replace($pattern, '%s', $line);

    foreach ($matches as $index => $match) {
        $matches[$index] = explode('|', trim($match, '{}'));
    }

    return $matches;
}


function printWords(array $args, array $matches, $line) {
    $current = array_shift($matches);
    $currentArgIndex = count($args);

    foreach ($current as $word) {
        $args[$currentArgIndex] = $word;

        if (!empty($matches)) {
                printWords($args, $matches, $line);
        } else {
                echo vsprintf($line, $args) . '<br />';
        }
    }
}

我想到的一种方法是使用 lexer技术,如逐个字符读取,创建适当的字节码,然后循环遍历它。它不是正则表达式,但它应该可以工作。

最佳答案

这个类完成了工作,尽管不确定它的效率如何:

class Randomizer {

    public function process($text) {
        return preg_replace_callback('/\{(((?>[^\{\}]+)|(?R))*)\}/x', array($this, 'replace'), $text);
    }

    public function replace($text) {
        $text = $this->process($text[1]);
        $parts = explode('|', $text);
        $part = $parts[array_rand($parts)];
        return $part;
    }
}

要使用它,您只需执行以下操作:

$line = "{This is my {sentence|statement} I {wrote|typed} on a {hot|cold} {day|night}.}";
$randomizer = new Randomizer( );
echo   $randomizer->process($line);

在正则表达式方面,我不是最好的,所以我无法真正解释为什么特定的正则表达式有效,对此感到抱歉。

顺便说一句,它返回随机字符串而不是所有可能的字符串。如果您需要所有字符串而不是随机字符串,请告诉我。我会更新答案..

关于php - 使用正则表达式的深度(无限)嵌套拆分词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36413253/

相关文章:

php - 如何在 PHP 中创建数字证书并导出到 .p12 文件?

php - 如何显示 MySQL 中的所有数据库和 foreach 数据库显示所有表

php - 拆分表列中的数据以进行搜索

php - 在 PHP 中将方法作为参数传递

c# - 混合起来,然后再次重新排序 .Net 2.0 中的数组

arrays - OpenGL 顶点数组所需的版本

regex - 如何提取ansible变量中的最后一个数字

c - char 数组是否需要比您打算使用的大一个字节? - C

java - 如何使用 Java 正则表达式防止字符重复

javascript - 在 Javascript 中使用 Regex 查找匹配的字符串?