Du mußt dem Regulären Ausdruck mitteilen, das auch "\n" ausgewertet werden sollen. Ansonsten bricht die regexp an einem "\n" ab. Allso muss der gesammte String als "single line" bearbeitet werden. Das ist die Option "s" allso hat man schonmal
$content =~ s!...!...!egs
Weiterhin wäre es gut, wenn du das matching ausschließt. Für "(...)" ist das "(?:...)" besser. Allso:
$content =~ s!(?:\$r->vor;\n){2,}!"vor(". @{[split(/;\n/, $&)]} .");\n"!egs
Dann kannst du auch das Matching ohne Probleme machen:
$content =~ s!((?:\$r->vor;\n){2,})!"vor(". @{[split(/;\n/, $1)]} .");\n"!egs
Zudem Frage ich mich warum das unveränderliche ";\n" matchst und hinten wieder einfügst, das ist völlig Sinnlos und kostet nur Zeit.
Dann leibt nur noch die Frage, warum du an einem funktionierenden Code was änderst und dich dann wunderst, daß es nicht mehr funktioniert. Ein wenig informieren über Reguläre Ausdrücke, solltest du dich schon. :-)