[eeei.gr Logo]
Επικοινωνία
Ταυτότητα
Μαθήματα Internet | Μαθήματα Προγραμματισμού | Net Business | Τα νέα του Internet | Ο Κόσμος του Αύριο

Split και Join (και λίγο substitution)

Θα πειραματιστούμε με τα δεδομένα του αρχείου data2.txt:

This is the first line of text.

And a second line of text.

---------

A third line of text.

Now a fourth line of text.

---------

The fifth line of text.

Finally, the sixth line of text.

Το πρόγραμμα που ακολουθεί κάνει διάφορες μετατροπές στο αρχείο χρησιμοποιώντας τις πολύ χρήσιμες εντολές Split και Join που μας βοηθούν να διαχειριστούμε τα περιεχόμενα μιας λίστας (array).

#!/usr/bin/perl -w

use strict;

Κατά τα γνωστά.

my $file ='data2.txt';

open (INFO, "<$file");

my @lines = <INFO>;

Ορίζουμε μια scalar μεταβλητή με τα στοιχεία του αρχείου, το ανοίγουμε δίνοντάς του το filehandle INFO και μετά μεταφέρουμε τα περιεχόμενα του INFO σε μια λίστα (array).

close (INFO);

Αφού κάναμε τη δουλειά που θέλαμε και πήραμε τα δεδομένα του data2.txt δεν υπάρχει λόγος να κρατάμε αυτή τη διαδικασία ανοικτή. Κλείνουμε λοιπόν το filehandle.

print "@lines\n";

Αυτό το κάναμε για να δούμε σε τι κατάσταση είναι τα δεδομένα μας τώρα που τα πήραμε από το αρχείο και τα βάλαμε μέσα σε μια array. Η εκτύπωση θα μας δώσει το ακόλουθο αποτέλεσμα:

This is the first line of text.

And a second line of text.

---------

A third line of text.

Now a fourth line of text.

---------

The fifth line of text.

Finally, the sixth line of text.

Πήραμε δηλαδή το ίδιο αποτέλεσμα με πριν. Η πηγή όμως είναι διαφορετική. Αντί για το περιεχόμενο του αρχείου, εδώ βλέπουμε μία μία όλες τις τιμές της array @lines.

my $long_line = join ("\n", @lines);

Η εντολή join παίρνει τα περιεχόμενα μιας array (εδώ της @lines) και τα ενώνει μεταξύ τους δημιουργούνται μια ενιαία σειρά χαρακτήρων (string) που αποθηκεύεται σε μια scalar (εδώ στην $long_line).

Για παράδειγμα αν δίναμε my $long_line = join ("*", @lines) αυτό θα σήμαινε:

Πάρε το περιεχόμενο της @lines και κόλλησε όλες τις τιμές μεταξύ τους χρησιμοποιώντας ως διαχωριστικό τον χαρακτήρα *. Έτσι το τελικό αποτέλεσμα θα ήταν:

This is the first line of text.*And a second line of text.*---------*A third line of text.*Now a fourth line of text.*---------*The fifth line of text.*Finally, the sixth line of text.

Στο τρέχον πρόγραμμα όμως κάναμε κάτι ιδιόμορφο. Είπαμε στην Perl ότι ο χαρακτήρας (ή ακολουθία χαρακτήρων) με την οποία θα «κολλήσει» τις τιμές είναι το \n δηλαδή η αλλαγή γραμμής. Έτσι, παρά το γεγονός ότι όλη η $long_line αποτελεί μια ακολουθία «κολλημένων» μεταξύ τους χαρακτήρων, η εμφάνισή της θα είναι:

print "$long_line\n";

This is the first line of text.

And a second line of text.

---------

A third line of text.

Now a fourth line of text.

---------

The fifth line of text.

Finally, the sixth line of text.

Παρατηρούμε λοιπόν ότι μπήκε μια καινούρια κενή γραμμή μεταξύ των γραμμών που περιείχαν κείμενο. Η εμφάνιση λοιπόν μπορεί να εξαπατά. Παρά τα κενά που υπάρχουν το παραπάνω υλικό αποτελεί μια και μοναδική ενιαία ακολουθία χαρακτήρων (απλώς ένας από αυτούς είναι ο \n).

my @dash_sep = split (/---------/, $long_line);

Αφού μάθαμε την join τώρα ήρθε η σειρά της split που κάνει ακριβώς το αντίθετο. Δηλαδή, παίρνει τα δεδομένα μιας scalar και τα χωρίζει στο προκαθορισμένο σημείο. Εδώ δηλαδή λέμε στην Perl να πάρει τη scalar $long_line και από αυτή να δημιουργήσει μια array (την @dash_sep). Το σημείο στο οποίο θα κοπεί η $long_line είναι οι 9 παύλες. Έτσι, η νέα array θα αποτελείται από τρεις τιμές.

print "@dash_sep\n";

This is the first line of text. And a second line of text.

(η πρώτη τιμή, δηλαδή η $dash_sep[0])

A third line of text. Now a fourth line of text.

(η δεύτερη τιμή, δηλαδή η $dash_sep[1])

The fifth line of text. Finally, the sixth line of text.

(η τρίτη τιμή, δηλαδή η $dash_sep[2])

Τώρα γνωρίζεται τις βασικές λειτουργίες των split και join. Επειδή όμως υποσχέθηκα στον Barry B. Floyd του οποίου το παράδειγμα χρησιμοποιώ εδώ, να δημοσιεύσω όλο τον κώδικά του θα συνεχίσουμε με μια μικρή εφαρμογή αντικατάστασης.

print "<HTML><HEAD><TITLE>Perl output</TITLE></HEAD>\n";

print "<BODY>\n";

Θέλουμε να δημιουργήσουμε μια Web σελίδα με περιεχόμενο κάπως διαφορετικό από εκείνο του data2.txt. Εδώ τυπώνουμε απλώς τον αρχικό κώδικα.

<HTML><HEAD><TITLE>Perl output</TITLE></HEAD>

<BODY>

foreach my $line (@dash_sep)

Για κάθε μεμονωμένη τιμή ($line) της @dash_sep

{

$line =~ s/line of text./text fragment. /g;

Δηλαδή, αντικατέστησε (s) το line of text (το περιεχόμενο της πρώτης //). με to text fragment. (το περιεχόμενο της δεύτερης //). Αυτή η αντικατάσταση πρέπει να γίνεται κάθε φορά που η Perl συναντά το περιεχόμενο της πρώτης // (g).

$line =~ s/\n//g;

Επειδή δεν μας αρέσουν τα πολλά κενά, λέμε την Perl να διαγράψει τις αλλαγές γραμμών, δηλαδή αντικαταστήσει την αλλαγή γραμμής (το \n) με το τίποτε (οι δύο // δεν περιέχουν τίποτε)

Το πρόγραμμα θα μπορούσε να τελειώσει εδώ. Εμείς όμως θέλουμε να κάνουμε κάτι ακόμη. Να τυπωθούν οι χαρακτήρες <HR><BR> πριν από τη δεύτερη τιμή ($dash_sep[1]) της @dash_sep.

if ($line =~ /^A third text/)

Έτσι δηλώνουμε ότι αν η αρχή (το σύμβολο ^ που στα αγγλικά ονομάζεται caret) της τιμής αποτελείται από την ακολουθία χαρακτήρων A third text

{

print " <HR><BR> \n";

}

τότε να τυπωθούν οι χαρακτήρες <HR><BR>

print " <P> $line </P> \n";

}

Να τυπωθεί το περιεχόμενο της $line μέσα στους χαρακτήρες <P> και </P>

print " </BODY>\n</HTML>\n";

Να τυπωθούν τα </BODY> και </HTML> με αλλαγή γραμμών μετά από αυτά.

Η τελική εκτύπωση λοιπόν θα είναι:

<HTML><HEAD><TITLE>Perl output</TITLE></HEAD>

<BODY>

<P>This is the first line of text. And a second line of text. </P>

<HR><BR>

<P>A third line of text. Now a fourth line of text. </P>

<P>The fifth line of text. Finally, the sixth line of text. </P>

</BODY>

</HTML>

Ολόκληρος ο κώδικας του παραπάνω προγράμματος είναι ο:

#!/usr/bin/perl -w

use strict;

my $file ='data2.txt';

open (INFO, "<$file");

my @lines = <INFO>;

close (INFO);

print "@lines\n";

my $long_line = join ("\n", @lines);

print "$long_line\n";

my @dash_sep = split (/---------/, $long_line);

print "@dash_sep\n";

print "<HTML><HEAD><TITLE>Perl output</TITLE></HEAD>\n";

print "<BODY>\n";

foreach my $line (@dash_sep)

{

$line =~ s/line of text./text fragment. /g;

print "@dash_sep\n";

$line =~ s/\n//g;

print "@dash_sep\n";

if ($line =~ /^A third text/)

{

print " <HR><BR> \n";

}

print " <P> $line </P> \n";

}

print " </BODY>\n</HTML>\n";


Τρέχουσα Ενότητα: Perl


 

Φιλικά - συνεργαζόμενα sites: Left Handed Products


© Eeei.gr 2009