If you are using regular expression matches for URLs to redirect, you may find that you get unexpected results, due to the redirections not being sorted correctly in the code that reads them from the database.
The code sorts the items by their array index of '<group-position>.<item-position>', which at first looks sensible, but this sorts alphabetically, not numerically. This means that if you have something like the following:
1 /fred\.(asp|html?) -> /index.php/fred 2 /jim\.(asp|html?) -> /index.php/jim_live_here ... 15 /(.*\.(asp|html?)) -> /index.php?redir=$1&type=catch_all
when the items are sorted alphabetically, you end up with:
1 /fred\.(asp|html?) -> /index.php/fred 15 /(.*\.(asp|html?)) -> /index.php?redir=$1&type=catch_all 2 /jim\.(asp|html?) -> /index.php/jim_live_here ...
This means that when your site is passed jim.asp, the 'catch-all' will be matched before the jim.asp match.
This is because the array's keys are set to '0.1', '0.2', ... '0.15' etc. The code can be made to sort numerically by padding the position in the array key to make '0.01', '0.02', ... '0.15' etc.
This can be done using sprintf, specifying the width for the position.
The code below does this, but first establishes the widths to use for the group and item positions by getting the number of characters required to hold the largest position number. The code replaces the get_for_url function in the models/redirect.php file: