use HTML::Entities qw( encode_entities ); sub text_to_html { my $terms = $_[1]; my ($terms_pat) = map "(?:$_)", join '|', map quotemeta, @$terms; ( my $html = $_[0] ) =~ s{ ( (?: (?!$terms_pat). )* ) ( $terms_pat+ ) | ( .+ ) }{ defined($1) ? encode_entities("$1") . "" . encode_entities("$2") . "" : encode_entities("$3") }xseg; return $html; } print text_to_html("best car wash & repair!!", [qw( car repair )]);