英文:
JavaScript highlight substring(s) within string
问题
function highlightSearchTerm(string, substring) {
const regex = new RegExp(`(${substring.split(' ').join('.*?')})`, 'ig');
return string.replace(regex, '<mark>$1</mark>');
}
英文:
I have a JavaScript String which looks like this:
From Windows to Linux
With JavaScript, how can I highlight the words From and Linux, via a substring which looks like this:
From Linux
so the string looks like this in the end:
<mark>From</mark> Windows to <mark>Linux</mark>
This is my current implementation of the function to do that job:
function highlightSearchTerm(string, substring) {
const regex = new RegExp(`(${substring})`, 'ig');
return string.replace(regex, '<mark>$1</mark>');
}
I call it like this:
highlightSearchTerm("From Windows to Linux", "from linux")
It works well, the only thing that is missing is to make it work when the substring has words which are not directly next to each other.
These substrings for instance work:
- from windows
- From
- to Linux
While these don't (Words are not directly next to each other in the main string):
- Windows Linux
- from To
- Linux from
答案1
得分: 1
简短回答
使用管道(|
)在术语之间调用highlightSearchTerm()
以获得所需的输出。
较长回答
答案涉及到你如何构建你的正则表达式。
该函数
function highlightSearchTerm(string, substring) {
const regex = new RegExp(`(${substring})`, 'ig');
return string.replace(regex, '<mark>$1</mark>');
}
重要的是要理解所创建的相应 RegExp
对象是怎样的,以及它如何对应可能直接书写的形式。
首先,如果我们调用
// 假设 substring = 'hello';
new RegExp(`(${substring})`, 'ig');
// 等同于: /(hello)/ig;
注意到这个分组项是在寻找单词 hello
。
现在,如果我们提供有多个我们想要的东西的输入,比如 hi
和 you
,如果我们将它们作为由空格分隔的单个字符串提供,例如:
const substring = 'hey you';
new RegExp(`(${substring})`, 'ig');
// 等同于: /(hey you)/ig
这将不会给我们想要的结果,因为解析器不是在寻找 hey
或 you
,而是将 hey you
视为一个短语。
然而,如果我们用管道(|
)将这些内容分隔开,我们会得到:
// 假设 substring = 'hey|you';
new RegExp(`(${substring})`, 'ig');
// 等同于: /(hey|you)/ig
现在它在字符串中寻找 hey
或 you
。因为在正则表达式中,管道字符表示“或”。
如果你想要扩展搜索以匹配多个短语,你可以用管道将每个特定的短语分隔开,例如:
new RegExp('(hey|you|that guy)', 'ig');
将会搜索单词 hey
和 you
,以及短语(包含空格)that guy
。
英文:
Short Answer
Call highlightSearchTerm()
with a pipe(|
) between the terms to achieve the desired output.
Longer Answer
The answer has to deal with how you are building your Regex.
The function
function highlightSearchTerm(string, substring) {
const regex = new RegExp(`(${substring})`, 'ig');
return string.replace(regex, '<mark>$1</mark>');
}
It's important to understand what the corresponding RegExp
object that is created reads like, and how it equates to a form that we would maybe write out directly.
First, if we call
// assume substring = 'hello';
new RegExp(`(${substring})`, 'ig');
// Equivalent: /(hello)/ig;
Notice that the grouped item is looking for the word hello
.
Now, if we supply something that has multiple things we want in it, such as hi
and you
then if we supply them as a single string separated by space, e.g.
const substring = 'hey you';
new RegExp(`(${substring})`,'ig');
// Equivalent: /(hey you)/ig
This will not give us what we want because instead of looking for hey
or you
, the parser is now looking hey you
as a phrase.
However, if we separate those things by a pipe (|
) we get
// assume substring = 'hey|you';
new RegExp(`(${substring})`,'ig');
// Equivalent: /(hey|you)/ig
This now looks for either hey
or you
in the string. This is because the pipe character in RegEx is the OR.
If you'd like to expand the search for multiple phrases, you separate each specific one by a pipe, e.g.
new RegExp('(hey|you|that guy)', 'ig');
Will search for the words hey
and you
and the phrase (space included) that guy
.
答案2
得分: 1
你可以像@Jhecht上面解释的那样使用管道**|,或者你可以分割你的子字符串**,像这样操作:
function highlightSearchTerm(string, substring) {
let arr = substring.split(' ');
arr.forEach(el => {
const regex = new RegExp(el, 'ig'),
temp = el;
el = el.replace(regex, `<mark>${el}</mark>`);
string = string.replace(temp, el);
})
return string;
}
let text = document.querySelector('div').innerHTML;
document.querySelector('div').innerHTML = highlightSearchTerm(text, 'From Linux');
这是如何返回true或false,如果你的文本包含子字符串:
let text = document.querySelector('div').innerHTML;
function isIncludesSubstring(text, substring){
let arr = substring.split(' '),
arrResult = [];
arr.forEach(el => {
const regex = new RegExp(el, 'ig');
arrResult.push(regex.test(text));
});
/* arrResult 包含 true 或 false,基于子字符串单词是否包含在文本中,
如果所有单词都包含在内,则函数将返回 true,否则将返回 false */
return arrResult.includes(false) ? false : true;
}
console.log(isIncludesSubstring(text, 'From Windows Linux'))
console.log(isIncludesSubstring(text, 'To Windows from'))
console.log(isIncludesSubstring(text, 'From Test Linux'))
希望对你有帮助!
英文:
You can use the Pipe | just like @Jhecht explained above, alternatively you can split your substring and doing it this way:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function highlightSearchTerm(string, substring) {
let arr = substring.split(' ');
arr.forEach(el => {
const regex = new RegExp(el, 'ig'),
temp = el;
el = el.replace(regex, `<mark>${el}</mark>`);
string = string.replace(temp, el);
})
return string;
}
let text = document.querySelector('div').innerHTML;
document.querySelector('div').innerHTML = highlightSearchTerm(text, 'From Linux');
<!-- language: lang-html -->
<div>From Windows to Linux</div>
<!-- end snippet -->
this is how you return true or false if your text includes the substring
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let text = document.querySelector('div').innerHTML;
function isIncludesSubstring(text, substring){
let arr = substring.split(' '),
arrResult = [];
arr.forEach(el => {
const regex = new RegExp(el, 'ig');
arrResult.push(regex.test(text));
});
/* arrResult includes true or false based on whether substring single word
is included in the text or not, the function will return true if all words are included
else it will return false */
return arrResult.includes(false) ? false : true;
}
console.log(isIncludesSubstring(text, 'From Windows Linux'))
console.log(isIncludesSubstring(text, 'To Windows from'))
console.log(isIncludesSubstring(text, 'From Test Linux'))
<!-- language: lang-html -->
<div>From Windows to Linux</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论