Вместо того, чтобы пытаться сопоставить два типа подстрок (то есть до @
и после @
) по отдельности, вы можете рассмотреть возможность сопоставления обоих сразу и использовать preg_replace_callback
заменить промежуточные символы на *
s:
$result = preg_replace_callback(
'/(?:^|(?<=;))([^@])([^@]*)([^@]@[^.])([^.]*)(?=[^.]\.)/',
function ($matches) {
return $matches[1] . str_repeat('*', strlen($matches[2])) . $matches[3] . str_repeat('*', strlen($matches[4]));
},
$str
);
https://regex101.com/r/VfS4Fh/2
Шаблон
(?:^|(?<=;))([^@])([^@]*)([^@]@[^.])([^.]*)(?=[^.]\.)
означает:
(?:^|(?<=;))
- Начать с начала строки или сразу после ;
([^@])
- Первая группа - захватить первый символ ([^@]*)
- Второйгруппа - захват не @
символов (замените на *
с позже) ([^@]@[^.])
- Третья группа - захват @
и символов на каждой стороне ([^.]*)
- Четвертая группа - захват не .
символов (замените на *
с позже) (?=[^.]\.)
- Ожидание не .
символа, за которым следует .
Затем замените на те же группы в том же порядке, за исключением того, что вторая и четвертая группы заменены на *
s.