[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Mutt Konfiguration



On Wed, May 24, 2006 at 10:28:34AM +0200, Udo Mueller wrote:
> Bitte ändere Zeile 35 von
> 
> if (m/<(.*\@.*)>/) {
> 
> nach
> 
> if (m/.*<(.*?\@.*?)>.*/) {

OK, ich sehe was Du machst, aber ich weiss noch nicht, warum (s.u.).

Mit dem initialen ".*" schiebst Du den Match ganz nach rechts, findest also
das am weitesten rechts stehende Paar "<...>". Das ".*" am Ende ist
ueberfluessig, weil es nicht geklammert ist, um etwas zu extrahieren.

Die nicht-gierige Variante *? von * nimmst Du, um zu vermeiden, dass Du bei
Strings wie "<foo><bar>" alles zwischen dem ersten "<" und dem letzten ">"
in der Klammer matchst. Besser (weil "selbst-dokumentierender") waere statt
dessen

  if (m/.*<([^>]+\@[^>]+)>/)

Dann steht dort eindeutig, dass wir a) alles haben wollen, was vor dem
ersten schliessenden ">" kommt und mindestens ein "@" enthaelt. Ausserdem
sagen wir mit dem "+" dass wir vor und nach dem "@" auch je mindestens ein
Zeichen erwarten, also degenerierte Adressen wie "<@>" oder "<@foo>" nicht
das sind, was wir erwarten.

Bei Regexps ist es sehr oft hilfreich, genau zu sagen, was man _nicht_ will
(auch fuer den NFA bzw. DFA "unten drunter", der dann nicht so viele
Alternativen ausprobieren muss, um zu sagen "klappt nicht!").

> Es gibt in meinem Keyring Einträge, in denen 2 < und 2 > vorkommen.
> Dann greift deine Rexexp nicht.

Hmmm, in meinem Keyring kommt das nicht vor. Wie sehen diese Eintraege denn
aus? Wenn Du mir das sagst, kann ich eine bessere Regexp angeben.

Das erste Beispiel war ad hoc (d.h. ich gebe zu: habe mir nicht die Specs
fuer den Keyring angesehen ;-). Die Eintraege nach "UID ..." scheinen mir
aber das zu sein, was in Emails in der From-Zeile steht, ggf. mit runden
Klammern fuer Kommentare, auch ohne "<...>" wie ich gerade sehe, aber wohl
kaum mit zwei Paar spitzen Klammern, ... hmm, ... es sei denn, die stehen
in "(...)" im Kommentar?

Um also auch Zeilen zu parsen, die gar keine "<...>" enthalten, muss das
Pattern aufwendiger werden. Wir naehern uns dann bald dem klassischen
Problem, Adressen nach RFC-2822 zu parsen. Die Loesung dazu geht in Jeffrey
Friedls hervorragendem Buch "Mastering Regular Expressions" ueber eine
komplette Buchseite ;-0

Wir koennen also zumindest schreiben:

  m/<?([^>\s]+\@[^>\s]+\.[^>\s]+)>?/

Damit matchen wir Email-artige Zeichenketten, vorzugsweise innerhalb der
spitzen Klammern, aber auch ohne diese. Auf jeden Fall aber nicht mehr
ueber zwei Klammerpaare hinweg. Und wir erwarten zumindest einen Punkt im
Domain-Teil (klappt dann nicht fuer halb spezifizierte interne Adressen,
aber aus dem Alter sollten wir raus sein).

	--jc

P.S. Proof of concept attached ;-)

-- 
  Ignorance more frequently begets confidence than does knowledge.
	-- Charles Darwin
#! /usr/bin/perl

while (<DATA>) {
  print $_;
  if ( m/<?([^>\s]+\@[^>\s]+\.[^>\s]+)>?/ ) {
    print "ok ", $1, "\n";
  } else {
    print "not ok\n";
  }
}

__END__
foo@bar.de
foo_bar@baz.de
foo+bar@baz.de
<foo@bar.de>
Real Name <foo@bar.de>
Real "Nick"  Name <foo@bar.de>
Real "Nick" Name <foo@bar.de> (and Comment)
Real (My Nick) "Nick" Name <foo@bar.de>
Real (auch @ RFC-2822) "Nick" Name <foo@bar.de>
(write me@my address) <foo@bar.de>
"Uh, oh me@oH_my" <foo@bar.de>
<foo@bar.de> "Uh, oh Me@Oh_My.address"

Reply to: