Как я могу заменить строку в абзаце другой строкой, не используя метод javascript .replace()
, и причина, по которой я не могу использовать метод .replace()
, заключается в том, что он выполняет замену только с первым соответствием слово в строке, чтобы добавить немного больше контекста, почему я не могу использовать .replace()
, я пытаюсь создать функцию маркировки, где пользователь сможет пометить текст в документе, маркер будет храниться на на стороне сервера, поэтому я запрашиваю маркеры документов, объект маркера содержит начальную и конечную позиции выделения в строке, поэтому я беру их в значения, чтобы извлечь текст и обернуть в тег mark
после этого мне нужно заменить текст уже тегом mark
на исходный текст, но есть случай, когда пользователь может выбрать слово, которое встречается в документе более одного раза, поэтому я не могу использовать замену поэтому мне нужно использовать начальную и конечную позиции выделения для .replace()
текста, например:
Lorem Ipsum Dolor Sit Amet, Заклинатель Lorem Adipiscing Elit. Vivamus ipsum Lorem eros, interdum ac cursus et, pulvinar Lorem at est. Integer nec rutrum ligula. В элитном классе есть элитный porttitor finibus.
и я хочу заменить 3-й «Lorem» на «Space», не касаясь остальных, я не могу использовать .replace()
. Есть ли другой способ для этого, возможно, с использованием начальной и конечной позиции выделения курсора?
/**
* Count the position and the number of the html tags
* to position the marker.
* @param {object} The chapter object
* @param {object} The marker object
* @return {object} Return the chapter with the marker on it.
*/
public characterCounter(chapter, marker): any {
const counters: any = {
htmlSimbol: null, // < or >
characters: 0,
startTags: 0, // count html until the start of the selection.
endTags: 0 // count html until the end of the selection.
};
/* Here we loop the blocks to find the righ
* one to place marker.
*/
chapter.blocks.some((block) => {
if (marker.blockId === block.blockId) {
/*
* Ones the block is founded start counting the
* characters from the string.
*/
const blockText = block.blockElement.text;
for (let i = 0; i < blockText.length; i++) {
/* when the loop reach the end of the selection
* and match with the number of characters counted
* that are not part of html tag the loop stop.
*/
if (counters.characters === marker.end) {
break;
} else {
/*
* if the loop crash wiht < then start counting
* characters as part of the html tags and stop
* when crash with >
*/
if (blockText[i] === '<' || blockText[i] === '>') {
counters.htmlSimbol = blockText[i];
} else if (blockText[i] !== '<' && blockText[i] !== '>' && counters.htmlSimbol !== null) {
if (counters.htmlSimbol === '<') {
if (counters.characters <= marker.start) {
counters.startTags += 1; // count the characters from the open html tags founded
} else {
counters.endTags += 1; // count the characters from the close html tags founded
}
} else if (counters.htmlSimbol === '>') {
if (counters.characters <= marker.start) {
counters.startTags += 2; // count the characters from the open html tags founded
} else {
counters.endTags += 2; // count the characters from the close html tags founded
}
counters.htmlSimbol = null; // change to null to know that is the end ot he html tag
}
} else if (counters.htmlSimbol === null) {
counters.characters += 1; // count the characters that are not part of html tag ( only text no html).
}
}
}
// Here is where i extract the text selected and wrapped in to the mark tag to then replaced on the original block of text
counters.endTags += counters.startTags;
marker.start += counters.startTags;
marker.end += counters.endTags;
const textSelected = blockText.substring(marker.start, marker.end);
const markerText = `<mark class="${marker.color}" *ngClass="" alt="${marker.id}">${textSelected}</mark>`;
block.blockElement.text = blockText.replace(textSelected, markerText);
return false;
}
});
return chapter;
}
/**
* Analyze the text block and add the marking
* to the right block of text.
* @param {array} The list of markers
* @param {array} The array of blocks
* @return {array} the array of block with the markers.
*/
public addMarking(markersList, chaptersArray): any {
let index = 0;
markersList.some((marker) => {
index = chaptersArray.map((e) => e.id).indexOf(marker.chapterId);
if (index > -1) {
this.characterCounter(chaptersArray[index], marker);
return false;
} else {
chaptersArray.some((chapter) => {
index = chapter.subChapters.map((e) => e.id).indexOf(marker.chapterId);
if (index > -1) {
this.characterCounter(chapter.subChapters[index], marker);
return false;
}
});
}
});
return chaptersArray;
}
проблема в том, что после того, как я применил тег mark
, после того, как я применил тег mark
к выделенному тексту, мне нужно заменить исходный текст на тег mark
, как вы можете видеть в код, который я использую .replace()
, поэтому у меня проблема в том, что пользователь выбирает слово более одного раза в длинном абзаце, поэтому текст заменяется в неправильном месте.