So I'll assume you're doing a rewrite rule to do this transformation and that you are doing a permanent external redirect. This may not be the case and if so, you may also need to use a RewriteCond. But the basic idea of the regular expression will be similar:
RewriteRule ^/?products/([0-9]+)_([0-9]+)\.asp$ http://www.example.com/products/?category_Id=$1&product_Id=$2 [R=301,L]
The RewriteRule has as it's first argument the incoming path of the request (not the domain, not the query string if any). It may or may not have the leading slash depending on whether your context is .htaccess or server level config. This code works either way.
This reads something like: if the path of the incoming request possibly starts with a slash, then "products/", then one or more digits, then an underscore, then one or more digits, then ends with ".asp" do an external redirect using HTTP 301 status (R=301), returning a URL that has the first set of digits after category_Id= and the second set after product_Id=, and stop processing more rewrite rules (L)
The parenthesis act in this context as a "capture group" and pick up all the matching characters for use later in the $1, $2 variables.
If you want to do this without the user knowing about it, it gets a little trickier -- an internal rewrite. If so, and you need help, please let us know if this is in the context of .htaccess or can be done within the server configuration (probably within a <VirtualHost> container). This example also assumes there's no existing query string you need to retain on the incoming URL -- if so, look at the QSA flag.
Hopefully I got this about right. My hit rate on these is about 30%, so I strongly caution you from assuming I did. I learned that "new math" where it was the idea that counted :-)