Toon posts:

[regex] condition subpatterns

Pagina: 1
Acties:

Verwijderd

Topicstarter
ik ben vanavond s bezig geweest met mijn mailtooltje, maar k loop tegen een klein probleempje aan.

Als ik mail ontvang, dan wil ik uit de header de afzender en zijn emailadres uitlezen. Dit had ik gedacht te doen dmv een reguliere expressie, maar...

meestal staat er
code:
1
From: "naampie" <email@adres.iets>

maar soms ook
code:
1
From: postmaster

Ik had een expressie bedacht met preg_replace om bij de bovenste "naampie" er uit te halen, alles leuk en wel, maar bij postmaster (of andersom) wil dat dus niet meer.
PHP:
1
<?$retval = preg_replace("/(?i)(from:)(.*)(?(?=.*)(<)(.*)(>))/","\\2",$header[$i]);?>

dus als er na \\2 nog wat komt, dan is de conditie van toepassing. Maar dit werkt dus niet. Ik heb zo ongeveer bijna alle combinaties en ingevingen wel gehad, dus ik ben t aardig zat :P. Is er iemand die hier iets meer ervaring met conditional subpatterns heeft en mij even kan helpen? :D

edit:

damn... topic titel 2 letters vergeten -> conditional subpatterns

  • Grum
  • Registratie: Juni 2001
  • Niet online
code:
1
2
3
4
5
6
7
8
9
10
11
!^From:\s+
(
   (?:
    "([^"]*)"
    \s+
    <([^>]*)>
   )
|
   (\S+) 
)
\s*$!mx

ongetest en uit de losse hand :)

Verwijderd

Topicstarter
[b]Op vrijdag 01 maart 2002 00:40 schreef Grum een regular expression :P
Thanks! Hij is bijna goed, ik ga ff uitvogelen wat dat ding van jou nu precies doet :P

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Grum:
code:
1
2
3
4
5
6
7
8
9
10
11
0  !^From:\s+
1  (
2   (?:
3    "([^"]*)"
4    \s+
5    <([^>]*)>
6    )
7  |
8    (\S+) 
9  )
10 \s*$!mx
Wat doet die ?: op regel 2? Is dat een soort "of het een of het ander"-constructie?
* drm had 'm nog nooit gezien :)
Je bent finally je underscore kwijt? ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Grum
  • Registratie: Juni 2001
  • Niet online
(?: .... ) betekend match alles tussen de : en ) maar include dat niet in je backreference

Dit houd dus in mijn voorbeeld in dat je ALTIJD in je match array de naam als eerste hebt (en als je een email hebt .. dan die als 2e)

nu bedenk ik me dat ie misschien niet 100% goed is ... hmmm BOEIEND ! ;) - ben der mee aant oefenen :P

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Grum:
(?: .... ) betekend match alles tussen de : en ) maar include dat niet in je backreference
Aha :) Thnx, redelijk handig

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Grum
  • Registratie: Juni 2001
  • Niet online
Tomato: leg dit es ff uit aub :P
PHP:
1
<?$theStrings   = array();$theStrings[] = 'From: "naampie" <email@adres.iets>';$theStrings[] = 'From: postmasteR'; $thePattern = ''; // komt zo foreach($theStrings as $theString){        $theMatch = preg_match($thePattern, $theString, $theHits);        print "\n'$theString' had this matches:\n";        print_r($theHits);}?>

met die code

en voor pattern deze regexp:
code:
1
2
3
4
5
6
7
$thePattern = '!^From:\s+
(?:
    "([^"]*)"
    \s+
    <([^>]*)>
)
\s*$!mx';

matched ie dit:
code:
1
2
3
    [0] => From: "naampie" <email@adres.iets>
    [1] => naampie
    [2] => email@adres.iets

dat klopt :) (dat was iig de bedoeling)
met deze regexp:
code:
1
2
3
$thePattern = '!^From:\s+
(\S+)
\s*$!mx';

matched ie dit:
code:
1
2
    [0] => From: postmasteR
    [1] => postmasteR

dat klopt wederom

maar waarom krijg ik 'lege' matches als ik die combine met (regexp|regexp) of (?:regexp|regexp) of zelfs (?:(regexp|regexp))

bv met deze regexp
code:
1
2
3
4
5
6
7
8
9
10
11
$thePattern = '!^From:\s+
(?:
   (\S+)
|
   (?:
     "([^"]*)"
     \s+
     <([^>]*)>
   )
)
\s*$!mx';

krijg ik dit als match
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'From: "naampie" <email@adres.iets>' had this matches:
Array
(
    [0] => From: "naampie" <email@adres.iets>
    [1] =>
    [2] => naampie
    [3] => email@adres.iets
)
 
'From: postmasteR' had this matches:
Array
(
    [0] => From: postmasteR
    [1] => postmasteR
)

en dan is dus mijn hele idee weg dat in [1] altijd de naam staat ;(

  • tomato
  • Registratie: November 1999
  • Niet online
Grum: Tomato: leg dit es ff uit aub :P
Je hebt geluk dat ik je sig tegenkwam :*
bv met deze regexp
code:
1
2
3
4
5
6
7
8
9
10
11
$thePattern = '!^From:\s+
(?:
   (\S+)
|
   (?:
     "([^"]*)"
     \s+
     <([^>]*)>
   )
)
\s*$!mx';

[..]

en dan is dus mijn hele idee weg dat in [1] altijd de naam staat ;(
Dat klopt, omdat in het eerste geval de eerste capturing parentheses niet gebruikt worden, maar ze worden wel geteld als $1 ($1 wordt dus leeg!).

Zal zo even een leukere maken :)

  • tomato
  • Registratie: November 1999
  • Niet online
Zoiets lijkt te werken...
code:
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
39
#!/usr/bin/perl

use strict;

my @headers = (
    'From: "naampie" <email@adres.iets>',
    'From: postmaster',
    'From: \'tomato\' hoi dit is leuk <>',
    'From: Grum <grum@got.net>'
);

foreach (@headers) {

    print "$_\n";

    if (
        /
            ^From:\s+
            [\"\']?  # Eventueel een quote
            (\w+)      # Naam in $1
            [\"\']?  # Eventueel een quote
            (?:      # Begin adres
                \s+
                <([^>]+)> # Adres in $2
            )?      # Adres is optioneel
            $
        /x ) {

        print "Naam: $1\n";
        print "Email: $2\n" unless !defined($2);
        print "\n";

    } else {

        print "Geen match\n\n";

    }

}


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
> perl -w header.pl
From: "naampie" <email@adres.iets>
Naam: naampie
Email: email@adres.iets

From: postmaster
Naam: postmaster

From: 'tomato' hoi dit is leuk <>
Geen match

From: Grum <grum@got.net>
Naam: Grum
Email: grum@got.net

Overigens vermoed ik dat er nog steeds constructies kunnen komen die je hiermee niet goed matcht. Misschien een idee om eens te zoeken naar een RFC over email headers ofzo?

  • Grum
  • Registratie: Juni 2001
  • Niet online
tnx 4 de uitleg :)

zit ook wel logica in .. in dat regexps ;)

Verwijderd

Topicstarter
thanks grum en tomato! k had net vanavond pas tijd om er naar te kijken en mee te prutsen, maar t is gelukt...

ik heb em een beetje omgebouwd tot
code:
1
/^From:\s+[\"\']?(\w+)[\"\']?(?(?=\s+).*)?/

omdat php t anders niet juist wou doen,
maar nu zit in beide gevallen de afzender op \\1 ;)
Pagina: 1