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

input given
$_ = aaa@z.com bbb@z.com ccc@z.com

output needed
$_ = aaa@something.com bbb@something.com ccc@something.com

if tried this

if ( $_ =~ m/^(\s+.+\@)(.+\.)(.+\s+) ){ $_ =~ s/^(\s+.+\@)(.+\.)(.*\s+)/$1something.$3/g; }
i get $_ as aaa@z.com bbb@z.com ccc@something.com
i am not able to replace in the first 2 email id

Replies are listed 'Best First'.
Re: replacing email id using regex
by shmem (Chancellor) on Jan 02, 2007 at 10:21 UTC

    The .+ is greedy by default. Non-greedy: .+?. Do you really have a space char at the beginning of the line? Why do you include spaces in your search pattern?

    $_ =~ s/(.+?\@)(.+?\.)(.+?)/$1something.$3/g;

    Without captures, using look-behind and look-ahead:

    $_ =~ s/(?<=\@).+?(?=\.)/something/g;

    See perlre.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: replacing hosts in e-mail addresses
by ferreira (Chaplain) on Jan 02, 2007 at 12:24 UTC

    l.frankline offered an easy solution. Let me provide an overkill solution.

    Many times the simple first solution you got turns to be a blocking stone when users change requirements and call for much more that they originally asked for. In the question, the Anonymous Monk is trying to achieve a replacement of the domain of an e-mail address and the solution he/she asked for was with regular expressions.

    That can be done also (in a overkill fashion) with an e-mail address parsing module to achieve a much more general solution. For instance, here's one way to do it with Email::Address module:

    use Email::Address; my $addresses = 'aaa@z.com bbb@z.com ccc@z.com "John Doe" <doe@z.com> +(John Doe) <j.d@z.com> '; my @emails = Email::Address->parse($addresses); for (@emails) { $_->address( $_->user . '@' . "something.com" ) if $_->host eq 'z. +com'; } my $new_addresses = join ' ', @emails;

    This code is able to do the host replacement task not just in simple addresses like aaa@z.com but also "John Doe" <doe@z.com> and (John Doe) <j.d@z.com>. No hiccup with quoting, comments, and other eccentricities in e-mail addresses.

Re: replacing email id using regex
by l.frankline (Hermit) on Jan 02, 2007 at 10:44 UTC

    Hi

    Easy solution:

    $_ = 'aaa@z.com bbb@z.com ccc@z.com'; $_=~s/(\@)([^\.]+)(\.)/$1something$3/g; print $_;

    Output:

    aaa@something.com bbb@something.com ccc@something.com

    regards,
    Franklin

    Don't put off till tomorrow, what you can do today.

Re: replacing email id using regex
by johngg (Canon) on Jan 02, 2007 at 10:31 UTC
    shmem has given you and answer using look around assertions but if you were to do this using regex captures you have to disambiguate the capture using braces. Your code is trying to replace with the variable $1something which, unsurprisingly, doesn't do what you want. Try something like

    use strict; use warnings; $_ = q{aaa@z.com bbb@z.com ccc@z.com}; print qq{$_\n}; s{([^@]+@)[^.]+}{${1}something}g; print qq{$_\n};

    which produces

    aaa@z.com bbb@z.com ccc@z.com aaa@something.com bbb@something.com ccc@something.com

    Cheers,

    JohnGG

    Update: shmem has pointed out that I'm completely wide of the mark here and that $1 and friends are never ambiguous.

      No, $1something isn't ambiguous, $<digit> variables never are:

      $ perl -le '$_ = "aaa\@z.com bbb\@z.com ccc\@z.com"; s/(.+?\@)(.+?\.)( +.+?)/$1something.$3/g;print' aaa@something.com bbb@something.com ccc@something.com

      In fact, a variable $1something is illegal:

      $ perl -e '$1something' Bareword found where operator expected at -e line 1, near "$1something +" (Missing operator before something?) syntax error at -e line 1, next token ??? Execution of -e aborted due to compilation errors.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        I didn't know that, thank you. You learn something new literally every day in the Monastery.

        Cheers,

        JohnGG