Conditional regex in add_rewrite_rule() for specific query filters & pagination

I’ve managed to workaround the problem. He’re the solution for further reference.

1) I have only 1 query var now:

function return_vars( $vars ) {
  $vars[] = 'filters';
  return $vars;
}

2) My rewrite rules changed to:

add_rewrite_rule( 'my-base/filters/([^\/]*)/([^&]*)/page/([0-9]{1,})/?', 'index.php?post_type=$matches[1]&filters=$matches[2]&paged=$matches[3]', 'top');
add_rewrite_rule( 'my-base/filters/([^\/]*)/([^&]*)/?', 'index.php?post_type=$matches[1]&filters=$matches[2]', 'top');

Rule 1: handles pagination
Rule 2: handles main page only

They have to be in this order.

3) Then, I filter the filters string more or less in this way

function my_pre_get_posts( $query ) {
  $filters = get_query_var('filters');

  // if no filter or if filters are odd, then return
  if(!$filters || count(explode("https://wordpress.stackexchange.com/", $k4w_filters)) % 2 != 0) return;

  // this is a global array with my 2 tax slugs in it
  global $CUSTOM_TAXES_S;

  $chunks = array_chunk(explode("https://wordpress.stackexchange.com/", $filters), 2);
  $filter_data = array_combine(array_column($chunks, 0), array_column($chunks, 1));

  // filter data, populate tax_data and field_data for queries
  foreach($filter_data as $key => $value) {
    if(in_array($key, $CUSTOM_TAXES_S)) {
        $tax_data[$key] = $value;
    } else {
        $field_data[$key] = $value;
    }
    $query->set('debug_tax_data', $tax_data);
    $query->set('debug_field_data', $field_data);
  }

  // if tax_data exist set tax_query
  if($tax_data) {
    foreach( $tax_data as $taxonomy => $slugs ) {
        // append tax query
        $tax_query[] = array(
            'taxonomy'  => get_tax_name($taxonomy), // that's a simple function that retrieves the taxonomy name from its slug
            'field'     => 'slug',
            'terms'     => explode(',', $slugs),
        );
    }
    $query->set('tax_query', $tax_query);
  }

  // if field_data exist set meta_query
  if($field_data) {
    foreach( $field_data as $key => $value ) {
        // append tax query
        $meta_query[] = array(
            'key'   => $key,
            'value'     => explode(',',$value),
            'compare'       => 'IN',
        );
    }
    $query->set('meta_query', $meta_query);
  }
}
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);

In this way I can even provide multiple terms for taxes, or values for fields, such as:

/my-base/filters/my-cpt/tax1/term1,term2/tax2/term1,term2/field1/val1,val2/goingon...

And it’ll work! With pagination too.

Obviously the code above works, but there has too be several checks to avoid issues and hacks (such as checking if a provided field name exists, or not, or if it’s in a filtrable-field list etcetera).

Hope this will help someone
🙂