I reopened because the dup (Select Query | Select Entires That Don't Start With A Number - MySQL) had the inverse condition -- "rows not starting with ..."
There is a significant optimization for rows starting with some consecutive set of characters, such as 1..9:
INDEX(col)
SELECT ... WHERE col >= '1'
AND col < CHAR(ORD('9') + 1)
This would scan only the 1..9 rows, not the entire table, such as the PHP approach would require, and such that all three answers on the other Question require.
A second reason this is not a dup of that other one -- the Question here is more about PHP vs MySQL. The main performance argument for doing it in MySQL is to save the transmission time.
If you need a fancier REGEXP, you could switch to MariaDB, which has (I think) the same regexp engine as PHP. If you need something too complex for SQL, even with a better regexp, then you may be forced to go to PHP. But even in that case, filter as much as you can in SQL -- to minimize the amount of data being shoveled over the 'wire'.