$s1 = "ThisIsATest";
$s2 = preg_replace("/(?<=[a-zA-Z])(?=[A-Z])/", "_", $s1);
echo $s2; // "This_Is_A_Test"
Пояснение:
Регулярное выражение использует два уточняющих утверждения (одно оглядывающееся назад и одно заглядывающее вперед), чтобы найти точки в строке, в которые следует вставить подчеркивание.
(?<=[a-zA-Z]) # a position that is preceded by an ASCII letter
(?=[A-Z]) # a position that is followed by an uppercase ASCII letter
Первое утверждение гарантирует, что в начале строки не вставлено подчеркивание.