简体   繁体   English

用<span>标签</span>包裹子字符串<span>(带嵌套)</span>

[英]Wrap sub-string with <span> tag (with nesting)

I have a function that wraps parts of a given string with < span> tag depending on search sub-string. 我有一个函数,可以根据搜索子字符串用<span>标签包装给定字符串的一部分。

Eg: 例如:

"Then came the night of the first falling star." “然后是第一颗流星的夜晚。”

it will return (and it's ok): 它会返回(没关系):

"Then came the night < span>of< /span> the < span>first< /span> falling star". “然后是</ span> <span>第一</ span>坠星的夜晚。”

for the "first of" search string. 用于“第一个”搜索字符串。 If we try search string "first of rs" (notice that "rs" contains in "fi RS t" that has already existed in our search string) and now it gives: 如果我们尝试搜索字符串“ rs of first” (请注意, “ rs”包含在我们的搜索字符串中已经存在的“ fi RS t”中),现在它给出:

"Then came the night < span>of< /span> the < span>fi< span>rs< /span>t< /span> falling star". “然后是</ span> <span> fi <span> rs </ span> t </ span>坠星的夜晚。

But what we want to see is the first result: 但是我们要看到的是第一个结果:

"Then came the night < span>of< /span> the < span>first< /span> falling star". “然后是</ span> <span>第一</ span>坠星的夜晚。”

 const markSubstring = (string, searchString) => { _.forEach(searchString.split(' '), function(value){ if(value != '') { let regEx = new RegExp('(' + value + ')', "ig"); string = string.replace(regEx, '<span>$1</span>'); } }); return _.map(string.split(/(<span>.*?<\\/span>)/), (item, key) => { let val = item.split(/<span>(.*?)<\\/span>/); if (val.length == 3) { return `<span>${val[1]}</span>` } return `${val}`; }); }; console.log(markSubstring('Then came the night of the first falling star.', 'first of')); console.log('---------'); console.log(markSubstring('Then came the night of the first falling star.', 'first of rs')); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

What is the best way to modify the function to get an expected result? 修改功能以获得预期结果的最佳方法是什么?

UPDATE 更新

Given string: Then came the night of the first falling star. 给定弦: 然后是第一颗流星的夜晚。

Some search queries and their expected results: 一些搜索查询及其预期结果:

came -> Then (came) the night of the first falling star. 来了->然后(来了)第一颗流星的夜晚。

came first -> Then (came) the night of the (first) falling star. 首先来到->然后(来到)(第一颗)流星的夜晚。

am ig first -> Then c(am)e the n(ig)ht of the (first) falling star. 首先是ig->然后是第一个流星的n(ig)ht。

first rs -> Then came the night of the (first) falling star. first rs->然后是(第一颗)流星的夜晚。

first rs am -> Then c(am)e the night of the (first) falling star. 首先是->然后是(第一颗)坠星的夜晚。

etc. 等等

So we divide search string by spaces and try to find each of these "sub-search queries" in the given string. 因此,我们将搜索字符串除以空格,然后尝试在给定的字符串中查找每个“子搜索查询”。

With new RegExp('(' + value + ')', "ig"); 使用new RegExp('(' + value + ')', "ig"); we have a one < span> displayed as a text in a string when search is nesting (not just styles that it has). 搜索嵌套时,我们有一个<span>显示为字符串中的文本(不仅仅是其样式)。 So the best option, I suppose, not to put it when the word (or its part has already highlighted). 因此,我认为最好的选择是不要在单词(或单词的一部分已经突出显示)时放它。

Edit 编辑

OK I added the following logic to perfect it. 好的,我添加了以下逻辑来完善它。

  1. Sort all search words by length so that the longest word gets searched first. 按长度对所有搜索词进行排序,以便最先搜索最长的词。 This way if a shorter word is searched, but is already contained as part of a longer one (that has been wrapped with <span> ), we know not to insert another span. 这样,如果搜索了一个较短的单词,但是已经包含在一个较长的单词中(已经被<span>包裹),我们知道不会插入另一个范围。
  2. We split each word from the string and make sure it hasn't already been wrapped with a <span> 我们从字符串中拆分出每个单词,并确保尚未用<span>

You can fix it by making sure each word is a full word and not part of another word. 您可以通过确保每个单词都是完整单词而不是另一个单词的一部分来解决此问题。

For example if we use the regex pattern: /(^|\\s)(first)(\\s|$)/gi we make sure that the word first must be followed by a space, beginning or end of a string. 例如,如果我们使用正则表达式模式: /(^|\\s)(first)(\\s|$)/gi ,请确保单词first后面必须带有空格,字符串的开头或结尾。 Therefore the word rs cannot be considered a word in this case. 因此,在这种情况下,不能将单词rs视为单词。

See it in action: 实际观看:

 const markSubstring = (string, searchString) => { var searchStrings = searchString.split(' ').sort(function(a, b){return b.length - a.length;}); _.forEach(searchStrings, function(value){ if(value != '') { let regEx = new RegExp('(' + value + ')', "ig"); let validationRegEx = new RegExp('<span>.*?(' + value + ').*?<\\/span>', "ig"); var words = []; _.forEach(string.split(' '), function(word) { if (!word.match(validationRegEx)) { word = word.replace(regEx, '<span>$1</span>'); } words.push(word); }) string = words.join(' '); } }); return _.map(string.split(/(<span>.*?<\\/span>)/), (item, key) => { let val = item.split(/<span>(.*?)<\\/span>/); if (val.length == 3) { return `<span>${val[1]}</span>` } return `${val}`; }); }; console.log(markSubstring('Then came the night of the first falling star.', 'first of')); console.log('---------'); console.log(markSubstring('Then came the night of the first falling star.', 'first of rs')); console.log('---------'); console.log(markSubstring('Then came the night of the first falling star. rs is also a word.', 'first of rs')); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM