WP_NAV_MENU filter targets all menus

You could try the following code snippet to override the primary menu:

/**
 * Override the primary menu.
 *
 * @param string  $nav_menu The HTML content for the navigation menu.
 * @param array   $args     Array of wp_nav_menu() arguments.
 * @return string $nav_menu
 */

function wpse_150003( $nav_menu, $args )
{
    //Override the primary menu:
    if( 'primary' === $args->theme_location )
        $nav_menu = 'My new menu';

    return $nav_menu;
}

add_filter( 'wp_nav_menu', 'wpse_150003', PHP_INT_MAX, 2 );

where we find the input arguments info from the source.

Notice that we return the $nav_menu value, instead of echoing it.

You could also filter my other attributes, for example menu_id.

You might also consider these filters:

  • wp_nav_menu_items
  • wp_nav_menu_{$menu->slug}_items

I hope this helps.