将可能以特殊字符开头或结尾并具有公共前缀的搜索短语包装为仅带有 SPAN 标记的整个单词 [英] Wrap search phrases that may start or end with special characters and have common prefixes as whole words only with SPAN tag
问题描述
我有这段代码可以突出显示数组中存在的单词,一切正常,只是它没有突出显示包含 '.' 的单词
I have this code to highlight words that exist in an array everything works fine except it didn't highlight the words that contain '.'
spansR[i].innerHTML = t[i].replace(new RegExp(wordsArray.join("|"),'gi'), function(c) {
return '<span style="color:red">'+c+'</span>';
});
我也尝试在每个单词中转义点
I also tried to escape dot in each word
for(var r=0;r<wordsArray.length;r++){
if(wordsArray[r].includes('.')){
wordsArray[r] = wordsArray[r].replace(".", "\\.");
wordsArray[r] = '\\b'+wordsArray[r]+'\\b';
}
}
我也尝试用那些来改变替换,但没有一个工作 "replace(".", "\.")" , "replace(".", "\.")" , "replace(".", "/.")" , "replace('.','/.')" , "replace('.','/.')" .
I also tried to change replace by those and non of them worked "replace(".", "\.")" , "replace(".", "\.")" , "replace(".", "/.")" , "replace('.','/.')" , "replace('.','/.')" .
这是一个简化的测试用例(我想匹配'free.')
This is a simplified test case (I want to match 'free.' )
<!DOCTYPE html>
<html>
<body>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var re = "\\bfree\\.\\b";
var str = "The best things in life are free.";
var patt = new RegExp(re);
var res = patt.test(str);
document.getElementById("demo").innerHTML = res;
}
</script>
</body>
</html>
推荐答案
在 JavaScript 中实现明确的词边界.
Implement an unambiguous word boundary in JavaScript.
这是一个不支持 ECMAScript 2018 及更新版本的 JS 版本:
Here is a version for JS that does not support ECMAScript 2018 and newer:
var t = "Some text... firas and firas. but not firass ... Also, some shop and not shopping";
var wordsArray = ['firas', 'firas.', 'shop'];
wordsArray.sort(function(a, b){
return b.length - a.length;
});
var regex = new RegExp("(^|\\W)(" + wordsArray.map(function(x) {
return x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}).join("|") + ")(?!\\w)",'gi');
console.log( t.replace(regex, '$1<span style="color:red">$2</span>') );
在这里,正则表达式看起来像 /(^|\W)(firas\.|firas|shop)(?!\w)/gi
,参见 演示.(^|\W)
捕获到 Group 1 ($1
) 开头的字符串或非单词字符,然后有第二个捕获组捕获其中的术语question 和 (?!\w)
负前瞻匹配不紧跟字符字符的位置.
Here, the regex will look like /(^|\W)(firas\.|firas|shop)(?!\w)/gi
, see demo. The (^|\W)
captures into Group 1 ($1
) start of string or a non-word char, then there is a second capturing group that catures the term in question and (?!\w)
negative lookahead matches a position that is not immediately followed with a word char.
wordsArray.sort
很重要,因为没有它,具有相同开头的较短单词可能会在较长单词出现之前获胜".
The wordsArray.sort
is important, as without it, the shorter words with the same beginning might "win" before the longer ones appear.
.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
是必须的转义搜索词中的特殊字符.
The .replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
is a must to escape special chars in the search terms.
支持lookbehinds的JS环境的变体:
A variation for JS environments that support lookbehinds:
let t = "Some text... firas and firas. but not firass ... Also, some shop and not shopping";
let wordsArray = ['firas', 'firas.', 'shop'];
wordsArray.sort((a, b) => b.length - a.length );
let regex = new RegExp(String.raw`(?<!\w)(?:${wordsArray.map(x => x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join("|")})(?!\w)`,'gi');
console.log( t.replace(regex, '<span style="color:red">$&</span>') );
正则表达式看起来像 /(?<!\w)(?:firas\.|firas|shop)(?!\w)/gi
,参见 演示.这里,(?<!\w)
负向后视匹配没有紧跟在字符字符前面的位置.这也使得捕获组变得多余,我将其替换为非捕获组 (?:...)
,并且替换模式现在只包含一个占位符 $&
代码>,插入整个匹配.
The regex will look like /(?<!\w)(?:firas\.|firas|shop)(?!\w)/gi
, see demo. Here, (?<!\w)
negative lookbehind matches a location that is not immediately preceded with a word char. This also makes capturing group redundant and I replaced it with a non-capturing one, (?:...)
, and the replacement pattern now contains just one placeholder, $&
, that inserts the whole match.
这篇关于将可能以特殊字符开头或结尾并具有公共前缀的搜索短语包装为仅带有 SPAN 标记的整个单词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!