2009-11-27 6 views
1

Quand j'écrisComment lire des paragraphes à la fois avec Perl?

#!/usr/bin/perl -w 
use strict; 

while(<DATA>) { 
    print "\n-------------------------\n\n"; 
    print; 
    <>; 
} 

après chaque « retour » je reçois une ligne. Pourquoi ne pas avoir le script suivant après chaque "retour" d'un paragraphe?

#!/usr/bin/perl -w 
use strict; 

local $/ = ""; 

while(<DATA>) { 
    print "\n-------------------------\n\n"; 
    print; 
    <>; 
} 

__DATA__ 
line one 
line two 
line three 
line four 
line five 

line six 
line seven 
line eigth 
line nine 

line ten 
line eleven 
line twelve 

Répondre

4

Dans votre premier script, avec la variable $/variable définie sur "\ n" par défaut, les données <DATA> ne retournent qu'une ligne à la fois.

je crois que le second script fait ce que vous voulez, il est juste que < > ne terminera pas la lecture sur un « retour », mais plutôt sur une < ctrl-d > en raison de votre $/réglage (comme quelqu'un d'autre a out < > lit à partir de STDIN mais je pense que vous le savez déjà et que vous l'utilisez pour réguler la sortie).

Si vous voulez vraiment régler la sortie avec 'return', vous devez en faire plus avec $/in the loop.

 
while(<DATA>) { 
    print "\n-------------------------\n\n"; 
    print; 
    $/ = "\n"; # default so that the following terminates the read on 'return' 
    <>; 
    $/ = ""; 
} 
+0

J'utiliserais '{$/=" \ n "; <>}' –

3

Je suppose que vous vous attendez à cette ligne

local $/ = ""; 

pour modifier le comportement des

<DATA> 

de continuer à lire jusqu'à la fin des données.

Mais en fait, il prend quelque chose comme ça

{ 
    local $/; # $/ becomes undef in this block 
    ... 
} 

pour permettre slurp mode (et contenir ce mode à la portée dans les {} Curlys).

En effet, il veut tout dire « oublier de penser à des nouvelles lignes comme la fin d'un dossier marqueur »,

... En outre, il y a un tie fighter dans votre code! Ce petit gars lira à partir de STDIN, pas de DATA - est-ce vraiment ce que vous voulez?

+1

En fait, le Perl "tie fighter" est le "<=>", que nous appelons parfois "l'opérateur de vaisseau spatial". –

+0

Je sais, mais <> est si proche que mon cerveau souriant du vendredi n'a pas pu résister à sauter ce petit détail. –

+5

Je pense que nous allons devoir inventer un opérateur '<-o->'. –

2

En utilisant <> cette façon (interactive) en mode paragraphe va être source de confusion. Il ne reviendra pas lorsque vous frapperez "return"; à la place, il lira jusqu'à ce qu'il obtienne une ligne non vide (le début d'un paragraphe), puis lira jusqu'à ce qu'il obtienne une ligne vide (la fin de ce paragraphe), puis continuera jusqu'à ce qu'il obtienne une ligne non vide (le début du paragraphe suivant - qui sera mis en mémoire tampon, non retourné) afin qu'il sache qu'il est débarrassé de toutes les lignes vides supplémentaires.

Peut-être que vous devriez utiliser:

local $/ = "\n"; <> 

à la fin de la boucle à la place. Ou peut-être POSIX :: getchar().