in reply to Performing substitutions on lines with special characters

gjb is right -- if the problem is that the hash key contains special characters but you want these to be treated as literals (i.e "$" matches an actual dollar-sign character in the string), then just say  s/\Q$item\E/$newitem/ (you don't need to put "quotemeta" operators around the right-side of the expression).

On the other hand, sometimes it's handy to make use of metacharacters, and always applying quotemeta operators would make this impossible. For example maybe the string is full-of-hyphenated-forms, and you just want to replace the hyphens with spaces - without removing "dashes" that operate as punctuation (having spaces around them instead of letters) - so a single regex with special characters is just what you want:

s/(?<=[a-z])-(?=[a-z])/ /g;
In this case, the trick is to make sure that you get all the magical characters you want into the regex exactly as they should be, without them getting interpolated into something else -- and you have to make sure that things like dollar and percent signs that need to be treated literally are all provided with literal backslash escapes. For example:
my %replacement; $replacement{'\$34\.50'} = '$17.25'; # ... key is match, value is replacement for my $item ( keys %replacement ) { s/$item/$replacement{$item}/g; }
Given a framework like that, do be careful about items that might interfere with one another (such that the final result might depend on the order in which edits are applied). This is the sort of thing where an AoA might be better than a hash:
my $replacements = [ ['S\&O 400', 'S&P 500'], ['\b400\b', '200'], # ... (or read these match/replace literals from a file) ] # this provides a stable, consistent order of application for my $edit ( @$replacements ) { s/$$edit[0]/$$edit[1]/; }