On MySQL prior to 8.0, trying to achieve this is quite a long way. In MySQL v8.0, one possible solution is using REGEXP_REPLACE like:
SELECT * FROM test
      ORDER BY 
      REGEXP_REPLACE(val, "[0-9]", "") ASC,
      ABS(REGEXP_REPLACE(val, "[A-Za-z]", "")) ASC;
However, since you're using MysQL v5.7, this is what I come up with:
SELECT val FROM 
(SELECT val, 
     LEAST(IF(LOCATE(0, val)=0,999,LOCATE(0, val)), 
     IF(LOCATE(1, val)=0,999,LOCATE(1, val)),  
     IF(LOCATE(2, val)=0,999,LOCATE(2, val)), 
     IF(LOCATE(3, val)=0,999,LOCATE(3, val)),  
     IF(LOCATE(4, val)=0,999,LOCATE(4, val)), 
     IF(LOCATE(5, val)=0,999,LOCATE(5, val)),  
     IF(LOCATE(6, val)=0,999,LOCATE(6, val)), 
     IF(LOCATE(7, val)=0,999,LOCATE(7, val)),  
     IF(LOCATE(8, val)=0,999,LOCATE(8, val)), 
     IF(LOCATE(9, val)=0,999,LOCATE(9, val))) lv
FROM test) t
ORDER BY SUBSTRING(val,1,lv-1) ASC, SUBSTRING(val,lv)+0 ASC;
The idea is to get the first number occurrence then use that to separate between the values before numbers and the numbers itself using LOCATE function:
LOCATE(1, val)
*translate to "Locate the number 1 in `val` column".
IF(LOCATE(1, val)=0, 999, LOCATE(1, val))
*translate to "If you can't locate the number 1 in `val`, return 999 
 otherwise return the location of it.".
Since these are numbers we're looking for, it's much easier because I'll only need to locate 0 to 9 number values. Then, if LOCATE return 0 as result, replace it with 999. I replace them because I'm using LEAST to return the smallest value; which is the first number occurrence:
LEAST(IF(LOCATE ..
After that, I make the query as a sub-query then uses the result from LEAST(IF(LOCATE .. as the centre of SUBSTRING in the ORDER BY:
SUBSTRING(val,1,lv-1)
*Will return the value before the first number occurrence. 
(e.g ZZZ-AA1 to ZZZ-AA OR ZZZ-AAA1 to ZZZ-AAA).
AND 
SUBSTRING(val,lv)
*Will return the value on the first number onwards. 
(e.g. ZZZ-AA1 to 1 OR ZZZ-AAA1 to 1).
Of course, if you want to look at the value, you can simply add the statement in ORDER BY to SELECT like :
SELECT val, SUBSTRING(val,1,lv-1) , SUBSTRING(val,lv)+0  FROM 
...
*If you notice, in the first SUBSTRING I've added lv-1 because without minus 1, the SUBSTRING will return together with the first number occurrence. And the second SUBSTRING I added +0 at the end because without plus 1 the result datatype is string so the ordering will mess up.
Demo fiddle