Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Match all emails from all subdomains for a domain except one..

by ehdonhon (Curate)
on Aug 08, 2003 at 23:56 UTC ( [id://282341]=perlquestion: print w/replies, xml ) Need Help??

ehdonhon has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow monks,

I have a tricky problem, I need a regular expression that I can compare to a group of email addresses. The addresses are all in the plain vanila format user@example.com or user@subdomain.example.com The situation is that I need the regular expression to match against any address from that particular domain, or any address from any subdomain of that domain, except for one special subdomain. For this example, I'll call that domain 'bar'.

For example:
smith@example.commatches
jones@example.commatches
jones@foo.example.commatches
jones@bar.example.comdoes not match
jones@baz.example.commatches

To complicate things, I can not break this up into multiple regular expressions. Also, I can't start it with '!~'. It must look like this:

for ( @addresses ) { if ( /.../ ) { # Fill in really cool regexp here print "$_ : match\n"; } else { print "$_ : fail\n"; } }

Is what I am asking for even possible? I thought maybe I could use a zero-width negative lookahead assertion to do this, but that extends beyond my experience. All help is appreciated!

Replies are listed 'Best First'.
Re: Match all emails from all subdomains for a domain except one.. (tye)
by tye (Sage) on Aug 09, 2003 at 05:01 UTC

    Something like this?

    /@(?!bar\.).*\.example\.com$/
    though that rejects "...@bar.foo.example.com" as well. This might be a good thing or a bad thing or a don't-care thing, you didn't specify.

    So you could instead go for:

    /@(?!bar\.example\.com$).*\.example\.com$/

    If your teacher will let you declare a variable, then you could even use:

    my $ex= ".example.com"; # ... if( /@(?!bar\Q$ex\E$)\Q$ex\E$/ ) {
    or
    my $ex= quotemeta(".example.com"); # ... if( /@(?!bar$ex$)$ex$/ ) {
    But all of these don't reject "...@foo.bar.example.com" which you might want to do, so you could go for:
    /@(.*\.)?(?!bar\.)[^.]+\.example\.com$/
    /@((.*\.)?(?!bar\.)[^.]+\.)?example\.com$/
    Updated based on shenme's reply.

                    - tye
      Whoops, that last RE fails against just "@example.com".

      I think I've got it working with negative look-behind, but try to think of other test cases.

      while( <DATA> ) { my( $expect, $string ) = split; my $result = $string =~ m/ @ (?: .* (?<! [@.] bar) \. )? example\.com $ /xi ? 'match' : 'fail'; printf " Got result '%s' when expecting '%s' on '%s'\n", $result, $expect, $string unless $result eq $expect; } __END__ match smith@example.com match jones@example.com match jones@foo.example.com fail jones@bar.example.com fail jones@foo.bar.example.com match jones@baz.example.com match jones@bbar.example.com fail jones@bar.example.com.com fail rednose@reindeer.org fail smythe@exzample.com fail teacher@make-an-example.com
Re: Match all emails from all subdomains for a domain except one..
by bobn (Chaplain) on Aug 09, 2003 at 00:10 UTC

    @addresses = <DATA>; chomp @addresses; for ( @addresses ) { if ( /@(?!bar.example.com$)/ ) { # Fill in really cool regexp here print "$_ : match\n"; } else { print "$_ : fail\n"; } } __END__ smith@example.com jones@example.com jones@foo.example.com jones@bar.example.com jones@bar.example.com.com jones@baz.example.com
    Results:
    smith@example.com : match jones@example.com : match jones@foo.example.com : match jones@bar.example.com : fail jones@bar.example.com.com : match jones@baz.example.com : match

    --Bob Niederman, http://bob-n.com

      Sorry, I guess I didn't make it clear enough, it also needs to fail on anything that isn't example.com. So, "jones@otherdomain.com" should fail.

        Sorry, I guess I didn't make it clear enough,

        I'll say.... this is now beyond my RE skills...

        Why all in in one un-negated RE? Is this for a postfix rule or some-such?

        --Bob Niederman, http://bob-n.com
        ...it also needs to fail on anything that isn't example.com

        Then just move the parens a little bit, and make the specific subdomain optional...

        /@(?!bar\.)?example\.com$/

        Update: Oh well, that's why it's called "free advice"

Re: Match all emails from all subdomains for a domain except one..
by Cody Pendant (Prior) on Aug 09, 2003 at 02:30 UTC
    Why not do it by a split instead of a regex? Is that against the rules too?

    ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss') =~y~b-v~a-z~s; print
      Yes, it has to be one regex... basically I'm using some third-party software (which I don't want to have to hack) that wants me to provide it with the contents of a regular expression in a config variable so that it can use it later for substitution. Something like this:
      # IN the config file $regexp = '@example.com'; $replacement = '@other.com'; # Many places nestled in the code $mail = s/$regexp/$replacement;

      I think I found what I was looking for. Thanks to all.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://282341]
Approved by hossman
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-03-29 06:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found