2015-12-24 28 views
6

ho questo semplice ingressorandomizzazione testo tra i delimitatori

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

uso Perl per identificare modelli tra due parentesi esterna delimitatori { e } e randomizzare i campi all'interno con il delimitatore interna ;.

sto ottenendo questo uscita

I have green fruit and cup of coffee 

questo è il mio lavoro script Perl

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

Il mio compito è quello di elaborare questo formato di input

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

Come ho capito, lo script dovrebbe saltare extern al chiusura braces { ... } nella prima parte del testo, che ha testo all'interno di parentesi aperte e chiuse:

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

Dovrebbe scegliere una parte casuale, simili

{red;green;orange} fruit 

o

cup of {tea;coffee;juice} 

Quindi va più in profondità:

green fruit 

Dopo tutto il testo viene elaborato, il risultato può essere uno dei seguenti

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. 

Lo script dovrebbe analizzare e casuale il testo successivo troppo. Per esempio

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 } 

Un'uscita esempio potrebbe essere

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. 

risposta

2

bella sfida. Quello che devi fare è trovare un set di parentesi graffe senza bretelle interne e scegliere un oggetto a caso da lì. Hai bisogno di farlo a livello globale. Questo sostituirà solo le parentesi "livello 1". È necessario eseguire il looping della stringa finché non vengono trovate altre corrispondenze.

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

output di esempio

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

Perché usi 'srand'? – choroba

+0

Pensavo ci fosse una buona ragione, ma (leggendo i documenti) no. –

3

Andando non avido è un pensiero buono, ma non abbastanza fare il trucco. E si può aggiungere un loop:

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

notare che il vostro input di esempio ha bretelle senza pari, quindi questo sembra uscita una spuria '}'

0

TXR soluzione. Ci sono molti modi per affrontarlo.

Supponiamo di leggere i dati dallo standard input. Che ne dite di leggere i dati in record che sono delimitati non dal solito carattere di nuova riga, ma piuttosto dallo schema delle scelte rinforzate? Facciamo ciò creando un oggetto adattatore di registrazione sul flusso di input standard. Il terzo argomento della funzione record-adapter è un booleano che indica che vogliamo mantenere il delimitatore di terminazione (la parte che corrisponde alla regex del delimitatore del record).

Così se i dati assomiglia a questo foo bar {bra;ces} xyzzy {a;b;c} d\n si trasforma in questi record: foo bar {bra;ces}, xyzzy {a;b;c} e d\n.

Elaboriamo quindi questi record come se fossero righe di testo che utilizzano il linguaggio di estrazione. Cadono in due modelli: linee che terminano nel modello di parentesi e linee che non lo fanno. Questi ultimi sono solo echeggiati. I primi vengono trattati come richiesto dalla sostituzione casuale della parentesi.

Iniziamo anche a inizializzare *random-state* in modo che il PRNG sia seminato per produrre una sequenza pseudo-casuale diversa per ogni ciclo. Se make-random-state è dato alcun argomento, si crea un oggetto di stato casuale inizializzato da parametri di sistema come l'ID del processo e il sistema di tempo: run

@(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) 

prova:

 
$ 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.