Regex allows you to encode requirements into a "pattern" with a lot more precision:
my @filtered = grep { m{^/tmp/[0-9]+\.hash$} } @all;
I use {} for delimiters since with the usual // ones every / in the pattern must be escaped. Then m is required in front (unlike with // delimiters where it may be omitted).
The anchor ^ matches the beginning of the string (and at yet other positions if the /m "modifier" is in effect)†. The /tmp seems to be the beginning of a path, but if there were (for example) leading spaces before it then the above wouldn't match (unless you change it to ^\s*/tmp so to allow for optional spaces). Consider your data carefully.
The $ matches the end of the string, or before the newline at the end if there is one (/m modifier changes this)†. To also match strings with more characters after hash remove the $.
The pattern itself sets down what you say in the problem description: there must be an integer, which varies, and the rest is fixed.
Perl's own (excellent) documentation comes with the tutorial perlretut.
† With the modifier, $str =~ /.../m, the string is treated as a multi-line string so that if there are linefeeds in it then ^ and $ in that regex match the beginning and end of each line as well.
The anchor to always match only the end of the string is \z (also see \Z which matches like $ but is insensitive to /m). See Assertions in perlre, and see answers on this page.