JavaScript高亮字符串中的子字符串。

huangapple go评论49阅读模式
英文:

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

现在,如果我们提供有多个我们想要的东西的输入,比如 hiyou,如果我们将它们作为由空格分隔的单个字符串提供,例如:

const substring = 'hey you';
new RegExp(`(${substring})`, 'ig');
// 等同于: /(hey you)/ig

这将不会给我们想要的结果,因为解析器不是在寻找 heyyou,而是将 hey you 视为一个短语。

然而,如果我们用管道(|)将这些内容分隔开,我们会得到:

// 假设 substring = 'hey|you';
new RegExp(`(${substring})`, 'ig');
// 等同于: /(hey|you)/ig

现在它在字符串中寻找 heyyou。因为在正则表达式中,管道字符表示“或”。

如果你想要扩展搜索以匹配多个短语,你可以用管道将每个特定的短语分隔开,例如:

new RegExp('(hey|you|that guy)', 'ig');

将会搜索单词 heyyou,以及短语(包含空格)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})`, &#39;ig&#39;);
    return string.replace(regex, &#39;&lt;mark&gt;$1&lt;/mark&gt;&#39;);
  }

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 = &#39;hello&#39;;
new RegExp(`(${substring})`, &#39;ig&#39;);
// 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 = &#39;hey you&#39;;
new RegExp(`(${substring})`,&#39;ig&#39;);
// 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 = &#39;hey|you&#39;;
new RegExp(`(${substring})`,&#39;ig&#39;);
// 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(&#39;(hey|you|that guy)&#39;, &#39;ig&#39;);

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');

这是如何返回truefalse,如果你的文本包含子字符串:

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(&#39; &#39;);

  arr.forEach(el =&gt; {
      const regex = new RegExp(el, &#39;ig&#39;),
            temp = el;
            
      el = el.replace(regex, `&lt;mark&gt;${el}&lt;/mark&gt;`);
      string = string.replace(temp, el);
  })
  return string;
}

let text = document.querySelector(&#39;div&#39;).innerHTML;

document.querySelector(&#39;div&#39;).innerHTML = highlightSearchTerm(text, &#39;From Linux&#39;);

<!-- language: lang-html -->

&lt;div&gt;From Windows to Linux&lt;/div&gt;

<!-- 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(&#39;div&#39;).innerHTML;

function isIncludesSubstring(text, substring){
  let arr = substring.split(&#39; &#39;),
      arrResult = [];
  arr.forEach(el =&gt; {
    const regex = new RegExp(el, &#39;ig&#39;);
    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, &#39;From Windows Linux&#39;))

console.log(isIncludesSubstring(text, &#39;To Windows from&#39;))

console.log(isIncludesSubstring(text, &#39;From Test Linux&#39;))

<!-- language: lang-html -->

&lt;div&gt;From Windows to Linux&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月6日 17:23:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75359419.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定