in reply to phrase match

For a small dataset such as this, I'd look closely at \b to see whether your word boundary conditions match \b's well enough for that to work for you. If so, just change your replacement expression to $sentence =~ s/\b($phrases_re)\b/\#$1\#/g; and you should be set.

For a larger dataset, or if \b doesn't quite work for you, take a look at Regexp::Assemble, which will both build you a more efficient regex and provide the anchor_word_begin and anchor_word_end settings, which may or may not deal more effectively with your "only match complete items" requirement.