2015-12-24 6 views
6

Ich habe diese einfache EingabeRandomisierung Text zwischen Begrenzern

I have {red;green;orange} fruit and cup of {tea;coffee;juice} 

I Perl verwenden Muster zwischen zwei externen Klammer zu identifizieren und Begrenzern {} und randomisieren die Felder im Inneren mit dem internen delimiter ;.

Ich bekomme diese Ausgabe

I have green fruit and cup of coffee 

Das ist mein Arbeits Perl-Skript

perl -plE 's!\{(.*?)\}[email protected]=split/;/,$1;$x[[email protected]]!ge' <<< 'I have {red;green;orange} fruit and cup of {tea;coffee;juice}' 

Meine Aufgabe ist es, dieses Eingabeformat

I have { {red;green;orange} fruit ; cup of {tea;coffee;juice} } and {nice;fresh} {sandwich;burger}. 

Wie ich zu verarbeiten verstanden, sollte das Skript extern überspringen al Schließ Zahnspange { ... } im ersten Textteil, der Text nach innen mit Öffnung und Schließung Klammern:

{ {red;green;orange} fruit ; cup of {tea;coffee;juice} } 

Es sollte einen zufälligen Teil wählen, wie dies

{red;green;orange} fruit 

oder

cup of {tea;coffee;juice} 

Dann geht es tiefer:

green fruit 

Schließlich Text verarbeitet wird, kann das Ergebnis einer der folgenden

I have red fruit and fresh burger. 
I have cup of tea and nice sandwich 
I have green fruit and nice burger. 
I have cup of coffee and fresh burger. 

Das Skript sollte den nächsten Text analysieren und randomisieren. Zum Beispiel

This {beautiful;perfect} {image;photography}, captured with the { {NASA;ESA} Hubble Telescope ; {NASA;ESA} Hubble Space Telescope} }, is the {largest;sharpest} image ever taken of the Andromeda galaxy { {— otherwise known as M31;— known as M31}; [empty here] }. 
This is a cropped version of the full image and has 1.5 billion pixels. { You would need more than {600;700;800} HD television screens to display the whole image. ; If you want to display the whole image, you need to download more than {1;2} Tb. traffic and use 800 HD displays } 

Ein Beispiel Ausgang

könnte
This beautiful image, captured with the NASA Hubble Telescope, is the 
sharpest image ever taken of the Andromeda galaxy — otherwise known as 
M31. 
This is a cropped version of the full image and has 1.5 billion 
pixels. You would need more than 700 HD television screens to display 
the whole image. 

Antwort

2

Nizza Herausforderung. Was Sie tun müssen, ist eine Reihe von geschweiften Klammern ohne innere Klammern zu finden, und wählen Sie ein zufälliges Element von dort. Sie müssen das global tun. Das wird nur die "Level 1" Klammern ersetzen. Sie müssen die Zeichenfolge durchlaufen, bis keine Übereinstimmungen mehr gefunden werden.

use v5.18; 
use strict; 
use warnings; 

sub rand_sentence { 
    my $copy = shift; 
    1 while $copy =~ s{ \{ ([^{}]+) \} } 
         { my @words = split /;/, $1; $words[rand @words] }xsge; 
    return $copy; 
} 

my $str = 'I have { {red;green;orange} fruit ; cup of {tea;coffee;juice} } and {nice;fresh} {sandwich;burger}.'; 
say rand_sentence($str); 
say ''; 

$str = <<'END'; 
This {beautiful;perfect} {image;photography}, captured with the { {NASA;ESA} 
Hubble Telescope ; {NASA;ESA} Hubble Space Telescope }, is the 
{largest;sharpest} image ever taken of the Andromeda galaxy { {— otherwise 
known as M31;— known as M31}; [empty here] }. This is a cropped version of the 
full image and has 1.5 billion pixels. { You would need more than {600;700;800} 
HD television screens to display the whole image. ; If you want to display the 
whole image, you need to download more than {1;2} Tb. traffic and use 800 HD 
displays } 
END 

say rand_sentence($str); 

Beispielausgabe

I have orange fruit and fresh sandwich. 

This beautiful photography, captured with the ESA Hubble Space Telescope , is the 
largest image ever taken of the Andromeda galaxy — otherwise 
known as M31. This is a cropped version of the 
full image and has 1.5 billion pixels. If you want to display the 
whole image, you need to download more than 1 Tb. traffic and use 800 HD 
displays 
+0

Warum Sie 'srand' verwenden Sie? – choroba

+0

Ich dachte, es gab einen guten Grund, aber (Lesen der Dokumente) nein. –

3

geht nicht gierig ist ein guter Gedanke, aber durchaus nicht tut den Trick. Und Sie können eine Schleife hinzu:

perl -plE 'while(s!\{([^{}]*)\}[email protected]=split/;/,$1;$x[[email protected]]!ge){}' 

Beachten Sie, dass Ihre Abtastwerteingang unerreichte Zahnspange hat, so scheint dies für die Ausgabe eines falschen ‚}‘

0

TXR Lösung. Es gibt viele Möglichkeiten, dies zu erreichen.

Angenommen, wir lesen die Daten von der Standardeingabe. Wie wäre es, wenn wir die Daten in Datensätzen lesen, die nicht durch den üblichen Newline-Charakter begrenzt sind, sondern eher durch das Muster der abgestuften Auswahl? Dazu erstellen wir ein Record-Adapter-Objekt über den Standard-Eingabestream. Das dritte Argument der record-adapter-Funktion ist ein Boolescher Wert, der angibt, dass der abschließende Begrenzer beibehalten werden soll (der Teil, der mit dem rekordbegrenzenden Regex übereinstimmt).

Wenn also die Daten wie diese foo bar {bra;ces} xyzzy {a;b;c} d\n sieht verwandelt es in diesen Aufzeichnungen: foo bar {bra;ces}, xyzzy {a;b;c} und d\n.

Wir verarbeiten diese Datensätze dann als Textzeilen, die die Extraktionssprache verwenden. Sie fallen in zwei Muster: Linien, die im geschweiften Muster enden, und Linien, die dies nicht tun. Letztere werden nur wiederholt. Erstere werden behandelt, wie es durch die zufällige Klammersubstitution erforderlich ist.

Wir initialisieren auch *random-state*, so dass der PRNG gesetzt wird, um eine unterschiedliche pseudozufällige Sequenz bei jedem Lauf zu erzeugen. Wenn make-random-state keine Argumente gegeben wird, erzeugt es einen zufälligen Statusobjekt von Systemparametern wie der Prozess-ID und Systemzeit initialisiert:

@(do (set *random-state* (make-random-state))) 
@(next @(record-adapter #/{[\w;]+}/ *stdin* t)) 
@(repeat) 
@ (cases) 
@*text{@switch} 
@ (do (put-string `@[email protected](first (shuffle (split-str switch ";")))`)) 
@ (or) 
@text 
@ (do (put-string text)) 
@ (end) 
@(end) 

Testlauf:

 
$ cat data 
I have {red;green;orange} fruit and cup of {tea;coffee;juice}. 
$ txr rndchoose.txr < data 
I have red fruit and cup of tea. 
$ txr rndchoose.txr < data 
I have orange fruit and cup of tea. 
$ txr rndchoose.txr < data 
I have green fruit and cup of coffee.