woocommerce_form_field in the foreach loop
https://github.com/woocommerce/woocommerce/blob/master/templates/checkout/form-billing.php#L39
refers to
https://github.com/woocommerce/woocommerce/blob/master/includes/wc-template-functions.php#L2607
So you can adapt the following code to your needs
function change_woocommerce_field_markup( $field, $key, $args, $value ) {
// Remove the .form-row class from the current field wrapper
$field = str_replace('form-row', '', $field);
// Wrap the field (and its wrapper) in a new custom div, adding .form-row so the reshuffling works as expected, and adding the field priority
$field = '<div class="form-row single-field-wrapper" data-priority="' . $args['priority'] . '">' . $field . '</div>';
return $field;
}
add_filter( 'woocommerce_form_field', 'change_woocommerce_field_markup', 10, 4 );
Or
In the template file (form-billing.php), in the foreach loop. Add div(s) with an if statement where needed.