#!/usr/bin/env perl use v5.36; use List::Util 'max'; my %price = ( 'Coca Cola' => 1.25, coke => 1.25, COLA => 1.25, Cola => 1.25, cola => 1.25, 'Pepsi Cola' => 1.25, pizza => 12.00, sandwich => 3.00, 'UNDEAD COLA' => undef, 'Undead Cola' => undef, 'Undead cola' => undef, 'undead cola' => undef, ); say 'Enter whole or partial name for key (just hit Return to exit).'; while (1) { print "\nName: "; my $name = ; chomp $name; unless (length $name) { say 'Exiting ...'; last; } unless ($name =~ /^[A-Za-z0-9 ]+$/) { say 'Only alphanumeric+space name searches allowed.'; next; } check_keys(\%price, $name); } sub check_keys ($hash, $name) { my %matches = map +($_ => 1), grep /$name/i, keys %$hash; if (keys %matches) { _printf_head($hash); if (exists $matches{$name}) { _printf($hash, 'EXACT', $name); delete $matches{$name}; } } else { say "No keys match '$name'."; return; } for (grep /^$name$/i, sort keys %matches) { _printf($hash, 'NO_CASE', $_); delete $matches{$_}; } for (sort keys %matches) { _printf($hash, 'PARTIAL', $_); } return; } sub _printf ($hash, $match, $key) { my $fmt = "%-7s %-@{[max map length, keys %$hash]}s "; $fmt .= defined $hash->{$key} ? "%.2f\n" : "%s\n"; printf $fmt, $match, $key, $hash->{$key} // ''; return; } sub _printf_head ($hash) { my $fmt = "%-7s %-@{[max map length, keys %$hash]}s %s\n"; printf $fmt, qw{Match Key Value}; printf $fmt, qw{----- --- -----}; return; }