#!/usr/bin/env perl use v5.36; use List::Util 'max'; my %price = ( 'Coca Cola' => 1.25, coke => 1.25, cola => 1.25, 'Pepsi Cola' => 1.25, pizza => 12.00, sandwich => 3.00, 'Undead Cola' => undef, ); say 'Enter whole or partial name for key (Enter 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 $fmt = "%-7s %-@{[max map length, keys %$hash]}s %s\n"; my @matches = grep /$name/i, keys %$hash; if (@matches) { printf $fmt, qw{Match Key Value}; printf $fmt, qw{----- --- -----}; if (exists $hash->{$name}) { @matches = grep !/^$name$/, @matches; printf $fmt, 'EXACT', $name, $hash->{$name} // ''; } if (@matches) { for my $match (sort @matches) { printf $fmt, 'PARTIAL', $match, $hash->{$match} // ''; } } } else { say "No keys match '$name'."; } return; } #### Enter whole or partial name for key (Enter to exit) Name: cok Match Key Value ----- --- ----- PARTIAL coke 1.25 Name: col Match Key Value ----- --- ----- PARTIAL Coca Cola 1.25 PARTIAL Pepsi Cola 1.25 PARTIAL Undead Cola PARTIAL cola 1.25 Name: Coca Cola Match Key Value ----- --- ----- EXACT Coca Cola 1.25 Name: Undead Cola Match Key Value ----- --- ----- EXACT Undead Cola Name: Cola Match Key Value ----- --- ----- PARTIAL Coca Cola 1.25 PARTIAL Pepsi Cola 1.25 PARTIAL Undead Cola PARTIAL cola 1.25 Name: cola Match Key Value ----- --- ----- EXACT cola 1.25 PARTIAL Coca Cola 1.25 PARTIAL Pepsi Cola 1.25 PARTIAL Undead Cola Name: ^cola$ Only alphanumeric+space name searches allowed. Name: (?{/path/to/evil_code}) Only alphanumeric+space name searches allowed. Name: Nightingale Tongues in Aspic No keys match 'Nightingale Tongues in Aspic'. Name: Exiting ...