Адреса очень похожи и можно было бы обойтись одним выражением с модификатором /g:
[0-9]+-([-\w]+)(\.html)?
Но поскольку в nginx нельзя при разборе адреса использовать /g, то каждый случай надо разбивать отдельно:
if ($uri ~ "/catalog/cat/[0-9]+-([-\w]+)\.html") {
rewrite /catalog/cat/[0-9]+-([-\w]+)\.html /$1 redirect;
}
if ($uri ~ "/catalog/[0-9]+-([-\w]+)/[0-9]+-([-\w]+)\.html") {
rewrite /catalog/[0-9]+-([-\w]+)/[0-9]+-([-\w]+)\.html /$1/$2 redirect;
}
if ($uri ~ "/catalog/[0-9]+-([-\w]+)/[0-9]+-([-\w]+)/[0-9]+-([-\w]+)\.html") {
rewrite /catalog/[0-9]+-([-\w]+)/[0-9]+-([-\w]+)/[0-9]+-([-\w]+)\.html /$1/$2/$3 redirect;
}
Можно еще попробовать сделать через map.