0

I had the following PHP Regex code, to replace all emails with a "[removed email]" replacement string; and it worked nicely:

$pattern = "/[^@\s]*@[^@\s]*\.[^@\s]*/"; 
$replacement = "[removed email]";
$body_highlighted = preg_replace($pattern, $replacement, $body_highlighted);

However, the email replacement strategy changed and now I need to actually show the emails but replace certain parts of it. I wanted to use str_replace on the numeric backreferences, like this, but it doesn't work.

$pattern = "/[^@\s]*@[^@\s]*\.[^@\s]*/"; 
$email_part = "$0";
$replacement = str_replace('a','b', $email_part); // replace all letter A with B in each email
$body_highlighted = preg_replace($pattern, $replacement, $body_highlighted);

Any idea what I am doing wrong?

1
  • str_replace runs at calling, not as a binding. There is no a in $0 so it remains unchanged. Likely you want to be using preg_replace_callback. Commented Sep 17, 2020 at 2:24

1 Answer 1

1

You are using str_replace on the actual string $0 and not the backreference it references, which is why it's not working.

You want to do the str_replace while you are doing the preg_replace, so you can use preg_replace_callback to use a callback function to get the "email part" and perform the string manipulation on it during the regex replacement.

To extract the first part of the email (before the '@') and change it:

$pattern = "/([^@\s]*)(@[^@\s]*\.[^@\s]*)/"; 
$body_highlighted = preg_replace_callback($pattern, 'change_email', $body_highlighted);

/* str_replace the first matching part on the email */
function change_email($matches){
  return str_replace('a','b', $matches[1]).$matches[2];
}

If you used this with, for example:
$body_highlighted = "My email is [email protected]";
the result: My email is [email protected]

Note the changes to the regex in $pattern to split the email in two parts - before @ and the part include @ and the domain name. These are accessed in the callback function as $matches[1] and $matches[2].

If you want to access the domain part of the email address (after the @):

You can split the email into 3 parts (before @, the @ and everything after the @) you can use the following:

$pattern = "/([^@\s]*)(@)([^@\s]*\.[^@\s]*)/"; 
$body_highlighted = preg_replace_callback($pattern, 'change_email', $body_highlighted);

function change_email($matches){
  return str_replace('a','b', $matches[1]).$matches[2].str_replace('y','z', $matches[3]);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your time and expertise. This is exactly what I was looking for. Much appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.