使用正则表达式的深(无限)NESTED分裂单词

时间:2016-04-04 21:31:20

标签: 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技术,如在char中的char char中,创建适当的字节码然后循环它。它不是正则表达式,但应该有效。

1 个答案:

答案 0 :(得分:1)

这门课完成了这项工作,虽然不确定它的效率如何:

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);

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

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