2016-04-04 13 views
6

WICHTIG EDIT: Da viele Leute gesagt, dass dies vermieden werden sollte und fast nicht in der Lage zu tun mit RegEx, ich werde Sie für einige andere Lösungen zu ermöglichen. Von nun an könnte jede Lösung als Antwort und schließlich als Lösung dienen. Vielen Dank!Tief (unendlich) VERSCHACHTELT Split Worte regex

Können sagen, ich habe:

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

gewünschte Ausgabe:

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. 

Mit dem Code von this answer auf meine vorherige Frage, ich bin derzeit in der Lage, die Worte zu spalten, kann aber nicht Figur die verschachtelten Werte aus. Könnte mir jemand helfen mit dem, was ich habe. Ich bin mir ziemlich sicher, dass ich irgendwo eine for-Schleife implementieren sollte, damit es funktioniert, aber ich kann nicht verstehen, wo.

$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 />'; 
     } 
    } 
} 

Ein Weg, ich in meinem Kopf bekam verwendet lexer Technik, wie in Lese char von char, entsprechende Bytecode erstellen und dann durch Schleife. Es ist keine Regex, aber es sollte funktionieren.

+0

Ist Ihre gewünschte Ausgabe die oben genannte Ausgabe, die Sie veröffentlicht oder was Sie derzeit produzieren? – Parfait

+0

Die obige Ausgabe ist, was ich erreichen möchte, funktioniert die aktuelle Prozedur für eine nicht verschachtelte Zeile. Überprüfen Sie die Variable $ line innerhalb der Funktion. –

+0

Ich glaube nicht, dass die erwartete Ausgabe korrekt ist. Das '| snowing 'ist ein OR mit dem vorherigen' {...} 'Block und die Ausgabe scheint dieser Regel nicht zu folgen. Anders gesagt: Es scheint keinen algorithmischen Weg zu geben, von Ihrer Eingabe zu der gewünschten Ausgabe zu gelangen. –

Antwort

1

Diese Klasse ist die Arbeit, allthough nicht sicher, wie effizient es ist:

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

es nutzen zu können, können Sie einfach tun:

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

Ich bin nicht der beste, wenn es um regelmäßige kommt Ausdrücke, so kann ich nicht wirklich erklären, warum diese bestimmte Regex funktioniert, sorry dafür.

Übrigens gibt es zufällige Zeichenfolgen und nicht alle möglichen Zeichenfolgen zurück. Lass mich wissen, wenn du alle Saiten brauchst anstatt einer zufälligen. Ich werde die Antwort aktualisieren ..

+0

Vielen Dank für den Beitrag, aber das ist nicht, was ich suche. Das Skript, das ich bereits geschrieben habe, arbeitet daran, alle möglichen Variationen der $ line-Variablen auszugeben (was ich tun muss), aber meine Lösung funktioniert nicht für verschachtelte Werte. Lies den Beitrag noch einmal, die '{my {words | sentence} | deins} 'sollte möglich sein. –

+0

@ J.Doe Ich lief '{my {words | sentence} | deine} und möglichen Ausgaben waren 'meine Wörter',' deine', 'mein Satz'. Ist das nicht die richtige Ausgabe? – Gogol

+0

@ J.Doe die Lösung, die ich Arbeiten für n-Level geschachtelt SpinStax veröffentlicht .. – Gogol