Re: [exim] catching newlines with ${sg {}{}{}}

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Phil Pennock
Ημερομηνία:  
Προς: Marten Lehmann
Υ/ο: exim-users
Αντικείμενο: Re: [exim] catching newlines with ${sg {}{}{}}
On 2008-06-20 at 14:48 +0200, Marten Lehmann wrote:
> I read this, but I don't understand where is the difference wether \n is
> expanded by exim to a newline (without using \N or using \\n) or using
> \N so PCRE transforms \n to a newline.


In this case, not much. Just be sure to also use \$ instead of $ to
anchor the end of the regexp, etc etc. \N removes the need for one
layer of backslashes so is generally less error-prone.

> > Try:
> > ${sg{$spam_report}{\N^.*\n\s*X-purgate-ID: (.*?)\n.*$\N}{\$1}}
>
> Thanks, this works. But it only works, because I know the exact format
> of $spam_report. How can I tell ${sg{}} to include \n to the matching
> characters of .*? I think in Perl this was done by the modifier /s.


Embed the modifier at the start of the regexp with (?s) -- see manual
pages perlre(1) (for Perl's documentation) or pcrepattern(3) (comes with
later versions of pcre). The latter describes this under "INTERNAL
OPTION SETTING".

> Is there any way on exim (besides to embed Perl) to extract a value like
>
> $id = $1 if $spam_report =~ /(^|\n)X-purgate-ID: (.*?)(\n|$)/s ?


Again, adding the \s* at the start so that X-purgate-ID: doesn't need to
be at the beginning of the line:

${sg{$spam_report}{\N(?s)^(?:.*\n|)\s*X-purgate-ID:\s+([^\n]+)(?:|\n.*)$\N}{\$1}}

The main reason it's longer is because sg is short for Perl's s///g so
you need to handle the lines which _don't_ match and don't get away with
conditional setting.

That's the one long regexp approach. The closest you'll get to a
conditional is to use map-filter on lists generated by using newline as
a separator:

  ${map\
        {<\n ${filter {<\n $spam_report}{match{$item}{\N^X-purgate-ID:\N}}}}\
        {${sg{$item}{\N^[^:]+:\s*(.*)\N}{\$1}}}\
        }


The straight regexp is probably faster, since you enter the regexp
engine just once.

Regards,
-Phil