Flow:
An array of strings comes from the server, for example, ["com"]
or ["c", "o", "m"]
.
It is necessary:
Highlight characters in links if there are matches with data that came from the server, that is, an array of strings.
Angular pipe
export class HighlightLettersPipe implements PipeTransform {
transform(text: any, regexGroups?: string[]): any {
if (text && regexGroups.length) {
regexGroups.forEach(element => {
let pattern = element.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
pattern = pattern.split(' ').filter((t) => {
return t.length > 0;
}).join('|');
let reg = new RegExp(pattern, 'gi');
text = text.replace(reg, match => {
return `<span class="replace-part">${match}</span>`;
});
});
return text;
} else {
return text;
}
}
}
Everything works fine when an array with one element arrives, for example ["com"]
.
Problem
When an array with several elements arrived - ["c", "o", "m"]
, the symbols are highlighted, but also the markup is inserted.
This is because the method replace
is used, which returns a new line each time.
After making the first pass and making the highlighting of the characters, a new line is returned with an added span
tag. Then a new pass is made and the symbols are already highlighted in the tag span
, but it is necessary that only the symbols of the original link are always highlighted.
In the end something comes out:
Maybe someone has encountered a similar problem and will help solve it. Thank you.
You could use this trick: instead of replacing directly to <span>
tags, add some placeholders like ~~~~~
for opening tag and -----
for closing one, and replace that with actual tags afterwards. This way it will not collide
regexGroups.forEach(element => {
// ...
let reg = new RegExp(pattern, 'gi');
text = text.replace(reg, match => {
return `~~~~~${match}-----`;
});
});
// this part must be outside your forEach() block
text = text.replace(/~~~~~/g, '<span class="replace-part">');
text = text.replace(/-----/g, '</span>');