You are trying to match 7-number-cities-starting-with-pa
URL to ^([^/]*)-letter-words-starting-with-
pattern in second rule.
These rules should work:
add_action( 'init' , 'se336474_rewrite_rules', 5 );
add_filter( 'query_vars', 'se336474_query_vars' );
function se336474_rewrite_rules()
{
// single pattern for URLs:
// site.com/cities-starting-with-pa/ => start_letter='pa'
// site.com/7-cities-starting-with-pi/ => start_letter='pi', length=7
add_rewrite_rule( '^(?:([0-9]+)-)?cities-starting-with-([^/]*)/?$', 'index.php?page_id=340&start_letter=$matches[2]&length=$matches[1]', 'top' );
//
// OR for URLs:
// site.com/cities-starting-with-pa/
// site.com/7-number-cities-starting-with-pi/
//
//add_rewrite_rule( '^cities-starting-with-([^/]*)/?', 'index.php?page_id=340&start_letter=$matches[1]', 'top');
//add_rewrite_rule( '^([0-9]+)-number-cities-starting-with-([^/]*)/?', 'index.php?page_id=340&start_letter=$matches[2]&length=$matches[1]', 'top');
}
function se336474_query_vars( $vars )
{
$vars[] = "start_letter";
$vars[] = "length";
return $vars;
}
You can use page_id=340
only if 340 is a page
type post, in other cases a redirection to canonical URL will be made.
About first rewrite rule syntax [ (?:([0-9]+)-)?
] you can read here.