How to match all special chars and replace with a custom highlight style

I want to highlight a part of string by surrounding it with a span with some background/color css. Currently i use this function which works good for normal strings.

function str_highlight_text(string, str_to_highlight) {
  var reg1 = new RegExp(str_to_highlight.replace(/[`~!@#$%^&*<>()_|+\-=?;:'",.<>\{\}\[\]\\\/]/g, '\\$&'), "gi"); 
  return string.replace(reg1, function(str) {return '<span style="background-color:#E4F0D4;color:#000;">'+str+'</span>'});
}

But the problem is that it doesn't work for special chars like "<", ">" and "&". For example, for & char, it returns &amp; in output.

except output

"&"problem when highlighted

Upvotes: 0

Views: 121

Answers (1)

sshine
sshine

Reputation: 16105

This seems to work fine, although there's a catch.

function hilight(haystack, needle) {
    return haystack.replace(
        needle,
        '<span class="hilight">' + needle + '</span>');
}

$(document).ready(function() {
    $("#target").html(function(idx, content) {
        return hilight(content, 'fancy &amp; neat');
    });
});
.hilight {
  font-weight: bold;
  color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="target">This is a fancy &amp; neat string.</div>

When you use the DOM (i.e. the HTML tree) as both your model and the view of your application, then updating the model means abstracting away the view-components like HTML special characters, existing <span> tags, and so on.

The elegant alternative is to create a model that is separate from your view using two-way bindings. (You can use several JavaScript libraries to achieve this, but React and Vue.js are popular choices today.) Here your model is the original string and the part of it to be highlighted, and the view is these two rendered in HTML. This way, your model is not infected with HTML tags and your view will be automatically re-rendered when the model changes.

See this Vue.js 1 example: Vue js text highlight filter

Upvotes: 1

Related Questions