Here is non-regular expression example:
$string = '$15?1?2/:1$16E/:2$17?6?7/:6$19E/:7$3E/';
$array = array_map( function( $item ) {
    return intval( $item );
}, array_filter( explode( '$', $string ) ) );
Idea is to explode the string by $ character, and to map that array and use the intval() to get the integer value.
Here is preg_split() example that captures the delimiter:
$string = '$15?1?2/:1$16E/:2$17?6?7/:6$19E/:7$3';
$array = preg_split( '/(?<=\$)(\d+)(?=\D|$)/', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
/*
  (?<=\$)                  look behind to see if there is: '$'
  (                        group and capture to \1:
    \d+                      digits (0-9) (1 or more times (greedy))
  )                        end of \1
  (?=\D|$)                 look ahead to see if there is: non-digit (all but 0-9) OR the end of the string
*/
With a help of this post, a interesting way to get every second value from resulting array.
$array = array_intersect_key( $array, array_flip( range( 1, count( $array ), 2 ) ) );