|
| Regulære udtryk Fra : Jimmy |
Dato : 19-06-03 18:39 |
|
Hej
Jeg har installeret en ny dæmon til at håndtere SMS, og den har et andet
format end det, jeg tidligere har fået hjælp med.
Jeg ønsker at parse de forskellige dele af den.
Eksempel på SMS (----- indsat af mig):
-----
From: 4526729999
From_SMSC: 4540390999
Sent: 03-06-19 18:57:17
Received: 03-06-19 18:57:27
Subject: GSM1_
Her er en SMS
-----
Forslag til parsing:
-----
my $SMS_Afsender = $sms =~ /From: (\d+)/ ? $1 : undef;
my $SC_Address = $sms =~ /From_SMSC: (\d+)/ ? $1 : undef;
my $Timestamp_SC_Sent = $sms =~ /Sent: (.+)/ ? $1 : undef;
my $Timestamp_Received = $sms =~ /Received: (.+)/ ? $1 : undef;
my $Modem = $sms =~ /Subject: (.+)/ ? $1 : undef;
my $SMS_Text = $sms =~ /\n(.+)/s ? $1 : undef;
-----
Specielt selve SMS'en er problematisk.
Jeg ved følgende:
- Det er altid det sidste i filen.
- Der er en tom linie efter headeren (From, From_SMSC mv)
- Der kan være flere felter i headeren end vist her
Hvordan skriver man udtrykket optimalt?
Er de andre udtryk i orden eller kan de fejle, hvis man forestiller sig, at
en ond bruger sender en lignende header som SMS-tekst?
Mvh
Jimmy
| |
Peter Makholm (19-06-2003)
| Kommentar Fra : Peter Makholm |
Dato : 19-06-03 19:00 |
|
"Jimmy" <nyhedsgruppe@get2net.dk> writes:
> -----
> From: 4526729999
> From_SMSC: 4540390999
> Sent: 03-06-19 18:57:17
> Received: 03-06-19 18:57:27
> Subject: GSM1_
>
> Her er en SMS
> -----
Det ser jo bare ud til at være modeleret over RFC822. Altså kan det
sikkert bare proceseres som var det en mail. Hvis man læser en SMS på
stdin:
while (<>) {
if (1../^$/) { # op til første tomme linje antages at være en header
/(.*?):\s(.*)/ && $header{$1} = $2;
} else { # resten er en del af selve beskeden
push @body, $_;
}
}
Eneste problem lige ved den måde er hvis en header kan opåtræde flere
gange, men ovenstående kan let ændres til at kunn eklare det på en
eller anden måde.
--
Peter Makholm | Yes, you can fight it, but in the end the ultimate
peter@makholm.net | goal of life is to have fun
http://hacking.dk | -- Linus Torvalds
| |
Peter Brodersen (19-06-2003)
| Kommentar Fra : Peter Brodersen |
Dato : 19-06-03 23:22 |
|
On Thu, 19 Jun 2003 20:00:12 +0200, Peter Makholm <peter@makholm.net>
wrote:
> /(.*?):\s(.*)/ && $header{$1} = $2;
Jeg får "Can't modify logical and (&&) in scalar assignment" - er det
en konstruktion, der er blevet tilladt med 5.8.x?
--
- Peter Brodersen
| |
Lars Balker Rasmusse~ (19-06-2003)
| Kommentar Fra : Lars Balker Rasmusse~ |
Dato : 19-06-03 23:43 |
|
Peter Brodersen <usenet@ter.dk> writes:
> On Thu, 19 Jun 2003 20:00:12 +0200, Peter Makholm <peter@makholm.net>
> wrote:
>> /(.*?):\s(.*)/ && $header{$1} = $2;
>
> Jeg får "Can't modify logical and (&&) in scalar assignment" - er det
> en konstruktion, der er blevet tilladt med 5.8.x?
Nej, Peter mente naturligvis
/(.*?):\s(.*)/ and $header{$1} = $2;
eller min egen favorit
$header{$1} = $2 if /(.*?):\s(.*)/;
--
Lars Balker Rasmussen Consult::Perl
| |
Peter Brodersen (19-06-2003)
| Kommentar Fra : Peter Brodersen |
Dato : 19-06-03 23:57 |
|
On Fri, 20 Jun 2003 00:42:40 +0200, Lars Balker Rasmussen
<lars@balker.org> wrote:
> $header{$1} = $2 if /(.*?):\s(.*)/;
Gisp...
Næste dumme spørgsmål:
>>> if (1../^$/)
Først troede jeg, det var en tastefejl, og rettede det blot til
if (/../^$/)
... men det giver selvfølgelig ikke det ønskede resultat.
1..-konstruktionen ringer bare ikke lige en klokke fra diverse
perlre-litteratur - hvor har jeg været en doven knægt og sprunget
afsnit over?
--
- Peter Brodersen
| |
Lars Balker Rasmusse~ (20-06-2003)
| Kommentar Fra : Lars Balker Rasmusse~ |
Dato : 20-06-03 06:37 |
|
Peter Brodersen <usenet@ter.dk> writes:
> Næste dumme spørgsmål:
>
>>>> if (1../^$/)
>
> Først troede jeg, det var en tastefejl, og rettede det blot til
> if (/../^$/)
> .. men det giver selvfølgelig ikke det ønskede resultat.
> 1..-konstruktionen ringer bare ikke lige en klokke fra diverse
> perlre-litteratur - hvor har jeg været en doven knægt og sprunget
> afsnit over?
Det er ikke en regex feature, det er en boolsk flipflip operator.
perlop skriver:
In scalar context, ".." returns a boolean value. The
operator is bistable, like a flip-flop, and emulates the
line-range (comma) operator of sed, awk, and various
editors. Each ".." operator maintains its own boolean
state. It is false as long as its left operand is false.
Once the left operand is true, the range operator stays true
until the right operand is true, AFTER which the range
operator becomes false again. It doesn't become false till
the next time the range operator is evaluated. It can test
the right operand and become false on the same evaluation it
became true (as in awk), but it still returns true once. If
you don't want it to test the right operand till the next
evaluation, as in sed, just use three dots ("...") instead
of two. In all other regards, "..." behaves just like ".."
does.
The right operand is not evaluated while the operator is in
the "false" state, and the left operand is not evaluated
while the operator is in the "true" state. The precedence
is a little lower than || and &&. The value returned is
either the empty string for false, or a sequence number
(beginning with 1) for true. The sequence number is reset
for each range encountered. The final sequence number in a
range has the string "E0" appended to it, which doesn't
affect its numeric value, but gives you something to search
for if you want to exclude the endpoint. You can exclude
the beginning point by waiting for the sequence number to be
greater than 1. If either operand of scalar ".." is a
constant expression, that operand is implicitly compared to
the $. variable, the current line number. Examples:
As a scalar operator:
if (101 .. 200) { print; } # print 2nd hundred lines
next line if (1 .. /^$/); # skip header lines
s/^/> / if (/^$/ .. eof()); # quote body
# parse mail messages
while (<>) {
$in_header = 1 .. /^$/;
$in_body = /^$/ .. eof();
# do something based on those
} continue {
close ARGV if eof; # reset $. each file
}
En genial feature, jeg bl.a. selv har brugt til at pille pod ud af
perl-filer:
while (<FILE>) {
if (/^=item/ .. /^=cut/) {
$pod .= $_;
}
}
--
Lars Balker Rasmussen Consult::Perl
| |
Thorbjoern Ravn Ande~ (20-06-2003)
| Kommentar Fra : Thorbjoern Ravn Ande~ |
Dato : 20-06-03 08:06 |
|
Lars Balker Rasmussen <lars@balker.org> writes:
> En genial feature, jeg bl.a. selv har brugt til at pille pod ud af
> perl-filer:
Der er ogsaa "..." varianten med nogen lidt andre randbetingelser.
Det giver forbloeffende lille kode hvis man anvender det fornuftigt :)
--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk/ravn
| |
Peter Makholm (20-06-2003)
| Kommentar Fra : Peter Makholm |
Dato : 20-06-03 07:42 |
|
Lars Balker Rasmussen <lars@balker.org> writes:
> Nej, Peter mente naturligvis
>
> /(.*?):\s(.*)/ and $header{$1} = $2;
Ups, precedensregler.
> eller min egen favorit
>
> $header{$1} = $2 if /(.*?):\s(.*)/;
Jeg bruger utrolig ofte modifiers, men lige præcis i dette tilfælde
hvor betingelsen er et pattern match hvor jeg bruger opfangede
variable, så har jeg svært ved det.
--
Peter Makholm | Why does the entertainment industry wants us to
peter@makholm.net | believe that a society base on full surveillance
http://hacking.dk | is bad?
| Do they have something to hide?
| |
|
|