Я написал эту функцию, которая направлена на замену слов или фраз в text
документе указанным выражением expr
учетом набора tokens
должны быть сопоставлены. Документ форматируется в новой строке.
function replaceTokens(text, tokens, expr, isline = false) {
tokens.forEach(word => {
if (expr[token]) {
if (isline) { // line regex
text = text.replace(new RegExp("(" + word.replace(/([\(\)'?*!"])/g, "\\$1") + ")", "gi"), expr);
} else {
text = text.replace(new RegExp("(" + word + ")", "gi"), expr[token]);
}
}
});
return text;
}
У меня две проблемы.
1) Для словарных токенов, таких как Lorem
, qui
и т.д., Он работает довольно хорошо, но я не могу избавиться от всего токена, т.е. Я не хочу сопоставлять qui
внутри слова типа quis
, но только данный токен в тексте. Использование ^word$
здесь не работает с группой захвата ^(word)$
[1 - SOLVED] в соответствии с первым ответом с new RegExp("\\b(" + word + ")\\b", "gi")
2) Для токенов фраз регулярное выражение, которое я использую, работает неправильно. Я хочу Lorem ipsum dolor sit amet
точную строку, такую как Lorem ipsum dolor sit amet
in
Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet etwas
он должен соответствовать только первой строке, а не второй строке.
Вот пример. Для (1) вы можете видеть, как qui
захватывается как токен и внутри слова quis
или aliquip
.
function replaceTokens(text, tokens, expr, isline = false) {
tokens.forEach(word => {
if (isline) { // line regex
text = text.replace(new RegExp("(" + word.replace(/([\(\)'?*!"])/g, "\\$1") + ")", "gi"), expr);
} else {
text = text.replace(new RegExp("\\b(" + word + ")\\b", "gi"), expr);
}
});
return text;
}
text = "Lorem ipsum dolor sit amet,\n consectetur adipiscing elit,\nsed do eiusmod tempor incididunt\nut labore et dolore magna aliqua.\nUt enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi\nut aliquip ex ea commodo consequat.\nDuis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur.\nExcepteur sint occaecat cupidatat non proident,\nLorem ipsum dolor sit amet etwas,\nsunt in culpa qui officia deserunt mollit anim id est laborum"
out = replaceTokens(text, ["Lorem", "ut", "qui"], "<strong>$1</strong>", false)
out_phrases = replaceTokens(text, ["Lorem ipsum dolor sit amet", "Duis aute irure dolor in reprehenderit"], "<strong>$1</strong>", true)
document.getElementById("in_text").innerHTML = text.replace(/\n/g, '<br/>')
document.getElementById("out_text").innerHTML = out.replace(/\n/g, '<br/>')
document.getElementById("out_phrases").innerHTML = out_phrases.replace(/\n/g, '<br/>')
<div id="in_text"></div>
<hr>
<div id="out_text"></div>
<hr>
<div id="out_phrases"></div>
Добавлен фрагмент jsfiddle, чтобы попробовать его.
Первый вопрос кажется довольно ясным: оберните строку Regex в ' \b
' (граница Word):
text = text.replace(new RegExp("\\b(" + word + ")\\b", "gi"), expr);
Это должно соответствовать только "Всего слов".
Второй вопрос, здесь вы можете проверить, если он начинается с текста, или он следует за точкой, либо после окончания текста, либо после точки, например:
text = text.replace(new RegExp("(^|\\.\\s?|,\\s?)(" + word.replace(/([\(\)'?*!"])/g, "\\$1") + ")($|\\.|,)", "gi"), expr);
Идея состоит в том, что она должна соответствовать SENTENCE
, а не line
. И предложение начинается либо в начале строки, либо после точки или запятой, и заканчивается либо точкой, либо запятой, либо в конце строки.
Не следует использовать параметр "Многострочный".
Редактировать2:
Я изменил группы, которые я сделал, на не-capture capture groupd, поэтому они не связывают замену групп. Теперь это:
text = text.replace(new RegExp("(?:^|\\.\\s?)(" + word.replace(/([\(\)'?*!"])/g, "\\$1") + ")(?:\\.|,|$)", "gi"), expr);
Теперь он работает на скрипке.
text = text.replace(new RegExp("\b(" + word + ")\b", "gi")
это не сработает, если вы попробуете изменить фрагмент ... почему? Я получаю и qui
и aliquip
\\b