Schrift
[thread]7154[/thread]

Split und Speichern oder mit RegEx speichern



<< >> 10 Einträge, 1 Seite
Spider-Mann
 2005-07-23 19:07
#56627 #56627
User since
2005-07-06
23 Artikel
BenutzerIn
[default_avatar]
Ich lese folgende $entry ein:

Format:
Zahl1;Datum1;Zahl2;Datum2 oder "yesterday";beliebigerString

Beispiele:
Quote
433076;16-02-2004;0;12-03-2005;--==EXECUTER==--
423595;15-04-2003;-746;yesterday;Keyfinder
442191;12-10-2004;0;yesterday;Spider-Mann
Ich brauche die Zahlen, den String und das Datum1 bzw. Datum2 bzw. "yesterday" in Epochsekunden.

Was ist besser, dies:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
my ($entry1, $entry2, $entry3, $entry4, $entry5) = split (/\s*;\s*/, $entry, 5);

if ($entry1 =~ /^\d+$/) {
$i::zahl1 = $entry1;
}

my ($day1, $month1, $year1) = split (/\s*-\s*/, $entry2, 3);
if ($day1 =~ /\d{2}/ and $month1 =~ /\d{2}/ and $year1 =~ /\d{4}/) {
$i::date1 = timegm (0,0,0,$day1,($month1 - 1),$year1);
}

if ($entry3 =~ /^\d+$/) {
$i::zahl2 = $entry3;
}

if ($entry4 =~ /^yesterday$/i) {
$i::date2 = $^T - 24*60*60;
} else {
my ($day2, $month2, $year2) = split (/\s*-\s*/, $entry4, 3);
$i::date2 = timegm (0,0,0,$day2,($month2 - 1),$year2);
}

$i::name = $entry5;

oder folgendes:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if ($entry =~ /^(\d+);(\d{2})-(\d{2})-(\d{4});(\d+);(\d{2})-(\d{2})-(\d{4})|(yes)(ter)(day);(.+)/i) {

$i::zahl1 = $1;

$i::date1 = timegm (0,0,0,$2,($3 - 1),$4);

$i::zahl2 = $5;

if ($6.$7.$8 =~ /^yesterday$/i) {
$i::date2 = $^T - 24*60*60;
} else {
$i::date2 = timegm (0,0,0,$6,($7 - 1),$8);
}

$i::name = $entry5;
}
\n\n

<!--EDIT|Spider-Mann|1122131386-->
Ishka
 2005-07-23 19:43
#56628 #56628
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Wieso eigentlich (yes)(ter)(day)? stattdessen könntest du doch auch (yesterday) schreiben, insbesondere, da du das nachher eh wieder zusammenhängst.

Abgesehen davon werden in beiden Teilen keine Fehler abgefangen.

Beim zweiten Programm fällt mir auf, daß du $8 zB. nach einem weiteren Regulären Ausdruck verwendest, was dann leer ist, dh. das was im anderen Ausdruckt gematched wurde drin ist (also nichts in dem Fall), von daher würde ich für die erste Möglichkeit tendieren.
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
Spider-Mann
 2005-07-23 19:52
#56629 #56629
User since
2005-07-06
23 Artikel
BenutzerIn
[default_avatar]
Weil ich drei Variable brauche,
(\d{2})-(\d{2})-(\d{4}) | (yes)(ter)(day).
Der senkrechte Strich bedeutet doch, das zwischen diesen Semikolon entweder ein Datum oder der String "yesterday" matcht, oder?

p.s.:
Im unteren Code ist auch noch ein Fehler, statt

$i::name = $entry5; muß es $i::name = $9; heißen.
coax
 2005-07-23 21:59
#56630 #56630
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/perl

 use strict;
 use warnings;

 use Time::Local;

 sub date2uts( $ );

 while(<DATA>) {
     if( m/ ^ (-?\d+?); (\d{2}-\d{2}-\d{4});
              (-?\d+?); (\d{2}-\d{2}-\d{4} | yesterday);
              (.+)                                      $ /x ) {

 my($num_a, $num_b, $date_a) = ( $1, $3, date2uts($2));

         my $date_b = $4 eq 'yesterday' ? timelocal(0, 0, 0, (localtime)[3 .. 5])
                                        : date2uts( $4 );

         printf("Number_A: %d\tDate_A: %d\nNumber_B: %d\tDate_B: %d\n",
                $num_a, $date_a, $num_b, $date_b);
     } else {
         printf(STDERR "Skipped: %s\n", $_);
     }
 }

 sub date2uts ( $ ) { # date to unixtimestamp
     if( $_[0] =~ /^(\d{1,2})-(\d{1,2})-(\d{4})$/ ) {
         return timelocal( 0, 0, 0, $1, $2 - 1, $3 - 1900 );
     } else {
         die "Date string not valid!\n";
     }
 }

_ _DATA_ _
433076;16-02-2004;0;12-03-2005;--==EXECUTER==--
423595;15-04-2003;-746;yesterday;Keyfinder
442191;12-10-2004;0;yesterday;Spider-Mann

Bei _ _DATA_ _ muessen die Leerzeichen zwischen den Unterstrichen weg.
,,Das perlt aber heute wieder...'' -- Dittsche
Spider-Mann
 2005-07-23 23:30
#56631 #56631
User since
2005-07-06
23 Artikel
BenutzerIn
[default_avatar]
Vielen Dank, ich werde Tage brauchen um den Code zu verstehen.
coax
 2005-07-24 05:58
#56632 #56632
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
[quote=Spider-Mann,23.07.2005, 21:30]Vielen Dank, ich werde Tage brauchen um den Code zu verstehen.[/quote]
vielleicht wird's so einfacher :)
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
while(<DATA>) {
    if( m/ ^ (-?\d+?); (\d{2}-\d{2}-\d{4});         # matcht: '-123; 12-05-2005;'
        (-?\d+?); (\d{2}-\d{2}-\d{4} | yesterday);  # matcht: '-123; 12-05-2005;'
               
               
               
       #    oder 'yesterday;'
        (.+)      &n
bsp;              &n
bsp;              &n
bsp; $ /x ) {

Der Regexp-Modifier '/x' macht's moeglich dass man den Regexp durch das Hinzu-
fuegen von Leerzeichen, Zeilenumbruechen und Kommentaren etwas uebersichtlicher
gestalten kann. );

Code: (dl )
1
2
my $date_b = $4 eq 'yesterday' ? timelocal(0, 0, 0, (localtime)[3 .. 5])
: date2uts( $4 );

Ist das gleiche wie:
Code: (dl )
1
2
3
4
5
6
my $date;
if( $4 eq 'yesterday' ) {
$date_b = timelocal(0, 0, 0, (localtime)[3 .. 5]);
} else {
$date_b = date2uts( $4 );
}


Code: (dl )
1
2
3
4
5
6
7
8
9
10
sub date2uts ( $ ) { # date to unixtimestamp
# wenn erstes Argument auf das Datumsformat zutrifft
if( $_[0] =~ /^(\d{1,2})-(\d{1,2})-(\d{4})$/ ) {
# dann gib Timestamp zurueck
return timelocal( 0, 0, 0,$1, $2 - 1, $3 - 1900 );
} else { # ansonsten Fehler
die "Date string not valid!
";
}
}


Grusz Christian.


Perl-Tags in Code-Tags geändert wegen Darstellungsfehlern\n\n

<!--EDIT|renee|1122199571-->
,,Das perlt aber heute wieder...'' -- Dittsche
Spider-Mann
 2005-07-24 12:17
#56633 #56633
User since
2005-07-06
23 Artikel
BenutzerIn
[default_avatar]
Danke. :)
Ich hoffe, du bist nicht wegen diesem Beitrag so früh noch wach gewesen.

Ganz so schlimm war es aber nicht, die RegEx und den Sub hatte ich schon verstanden.

Und was die Zeile dazwischen macht wusste ich eigentlich auch,
aber etwas wissen heißt ja nicht automatisch, daß man es auch verstanden hat.
Spider-Mann
 2005-07-24 13:07
#56634 #56634
User since
2005-07-06
23 Artikel
BenutzerIn
[default_avatar]
Dafür weiß ich nicht genau wofür
Code: (dl )
sub date2uts( $ );
am Anfang gut ist.
Wird der Sub dadurch beim Start grundsätzlich geladen und muß nicht bei jedem Aufruf neu geladen werden? Wobei ( $ ) dafür sorgt, daß eine Variable übergeben werden muß?
[E|B]
 2005-07-24 14:18
#56635 #56635
User since
2003-08-08
2561 Artikel
HausmeisterIn
[Homepage] [default_avatar]
[quote=Spider-Mann,24.07.2005, 11:07]Dafür weiß ich nicht genau wofür
Code: (dl )
sub date2uts( $ );
am Anfang gut ist.
Wird der Sub dadurch beim Start grundsätzlich geladen und muß nicht bei jedem Aufruf neu geladen werden? Wobei ( $ ) dafür sorgt, daß eine Variable übergeben werden muß?[/quote]
Ja, es wird ein Parameter verlangt. Siehe auch perldoc perlsub.
Gruß, Erik!

s))91\&\/\^z->sub{}\(\@new\)=>69\&\/\^z->sub{}\(\@new\)=>124\&\/\^z->sub{}\(\@new\)=>);
$_.=qq~66\&\/\^z->sub{}\(\@new\)=>93~;for(@_=split(/\&\/\^z->sub{}\(\@new\)=>/)){print chr;}

It's not a bug, it's a feature! - [CGI-World.de]
pq
 2005-07-24 19:21
#56636 #56636
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[E|B
,24.07.2005, 12:18]Siehe auch perldoc perlsub.

Wiki:perldoc perlsub
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
<< >> 10 Einträge, 1 Seite



View all threads created 2005-07-23 19:07.