There is one problem with mod_rewrite, about which there are probably 15 million cones already stuffed: it scans the list of rules again and again until the URL can be changed.
Very often, endless cycles are also obtained (for example, adding an extension — it is added again and again, unless you specifically restrict regexp), over which you have to break your head because of unaccustomed use. All hopes for the modifier [L] are in vain - it only immediately starts the next iteration of processing. And without an infinite loop, extra iterations do not add speed of operation :-)
I want to share a fairly simple and versatile means of dealing with such a feature, which found only that :-)
')
RewriteCond %{ENV:REDIRECT_FINISH} !^$
RewriteRule ^ - [L]
#
RewriteRule ^/?page/([az]+)$ read.php?page=$1 [E=FINISH:1,L,QSA]
RewriteRule ^.*$ 404.php [E=FINISH:1,L]
What's going on here? As soon as we have made the final URL conversion, we set the FINISH environment variable, and on the next iteration Apache will copy the old variable environments with the REDIRECT_ prefix, see the set REDIRECT_FINISH and finish the work. Telemarket :-)
PS: The built-in rewrite-engine in nginx is deprived of this problem from birth, but this is so, by the way ;-)
UPDATE: In comments, it was even shorter, with unconditional cutting of everything after the first iteration:
# Don't loop.
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* — [L]