Skip to content
Advertisement

Match and replace a substring while ignoring special characters

I am currently looking for a way to turn matching text into a bold html line. I have it partially working except for special characters giving me problems because I desire to maintain the original string, but not compare the original string.

Example:

Given the original string:

Taco John's is my favorite place to eat.

And wanting to match:

is my 'favorite'

To get the desired result:

Taco John's <b>is my favorite</b> place to eat.

The way I’m currently getting around the extra quotes in the matching string is by replacing them

let regex = new RegExp('('+escapeRegexCharacters(matching_text.replace(/[^a-z 0-9]/gi,''))+')',"gi")
let html= full_text.replace(/[^a-z 0-9]/gi,'').replace(regex, "<b>$1</b>")}}></span>

This almost works, except that I lose all punctuation:

Taco Johns <b>is my favorite</b> place to eat

Is there any way to use regex, or another method, to add tags surrounding a matching phrase while ignoring both case and special characters during the matching process?

UPDATE #1:

It seems that I am being unclear. I need the original string’s puncuation to remain in the end result’s html. And I need the matching text logic to ignore all special characters and capitalization. So is my favorite is My favorite and is my 'favorite' should all trigger a match.

Advertisement

Answer

Instead of removing the special characters from the string being searched, you could inject in your regular expression a pattern between each character-to-match that will skip any special characters that might occur. That way you build a regular expression that can be applied directly to the string being searched, and the replacing operation will thus not touch the special characters outside of the matches:

let escapeRegexCharacters = 
         s => s.replace(/[-[]/{}()*+?.\^$|]/g, "\$&"),
    full_text = "Taco John's is My favorite place to eat.";
    matching_text = "is my 'favorite'";
    regex = new RegExp(matching_text.replace(/[^a-zsd]/gi, '')
                .split().map(escapeRegexCharacters).join('[^a-zsd]*'), "gi"),
    html = full_text.replace(regex, "<b>$&</b>");

console.log(html);
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement