It's quite easy, actually:
Change the generated permalink structure so that it ends with the post ID and not the post slug (but it still contains the post slug):
// After you registered the post type:
register_post_type( 'ex_article', $args );
// .. run this code:
$wp_rewrite->extra_permastructs['ex_article']['struct'] = 'sa/%...
So you can quickly achieve this by changing 'category' to 'genre' you can do this in Settings > Permalinks and change 'Category Base' to 'genre'.
To do it with code and keep both 'category' and 'genre' as prefixes is possible with a rewrite rule, however someone else may know a better way. You also need to only run flush_rewrite_rules() once so you need ...
The WP function get_category_link() will do the trick.
* Gets the URL for a category term archive based on the category's slug.
* @param string $category_slug The slug of the category to get the category arcive for.
* @return string The category (term) archive URL. Empty string on error.
function wpse_get_category_url_by_slug( $category_slug ...
First, you need to register the %office% rewrite tag:
// First, add the rewrite tag.
add_rewrite_tag( '%office%', '([^/]+)', 'post_type=office_members&office_name=' );
// Then call add_permastruct().
add_permastruct( 'office_members', ... );
Then, add the custom office_name arg to the public query vars so that WordPress reads/parses it from the URL:
I recently wrote an answer to a similar question, so be sure to check it out because you can just use the same code, except you'd use the post type dvposts and not ex_article, and use the structure d/%dvposts%/%post_id%.
But the trick there is quite simple: When you call register_post_type() with rewriting enabled, WordPress always appends the post slug ...