Я нашел ответ в отличном объяснении mod_rewrite и mod_alias
Проблема в том, что mod_rewrite всегда происходит до mod_alias, независимо от порядка, в котором они размещены в .htaccess.Это обратный порядок, необходимый для этой ситуации.
Хитрость заключается в том, чтобы использовать RewriteRule [R=301]
вместо redirect 301
и, следовательно, использовать mod_rewrite для всего, вместо того, чтобы смешивать его с mod_alias.
Полное решение выглядит следующим образом:
RewriteEngine on
RewriteBase /
RewriteRule ^oldpage1.html /newpage1.php [R=301,L]
RewriteRule ^oldpage2.php /newpage2.php [R=301,L]
RewriteRule ^oldpage3.php /newpage3.php [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1