仅使用 SPAN 标签将可能以特殊字符开头或结尾且具有公共前缀的搜索短语包装为整个单词

2024-04-21

我有这段代码来突出显示数组中存在的单词,一切正常,只是它没有突出显示包含“.”的单词。

spansR[i].innerHTML = t[i].replace(new RegExp(wordsArray.join("|"),'gi'), function(c) {
                return '<span style="color:red">'+c+'</span>';
            });

我还尝试转义每个单词中的点

 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(".", "/ .")" 、 "替换('.','/.')" 、 "替换('.','/.')" 。

这是一个简化的测试用例(我想匹配 '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 中实现明确的单词边界。

以下是不支持 ECMAScript 2018 及更高版本的 JS 版本:

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, see demo https://regex101.com/r/4sg00q/2. The (^|\W)捕获到第 1 组($1) 字符串或非单词字符的开头,然后有第二个捕获组来捕获有问题的术语,并且(?!\w)负向先行匹配后面没有紧跟单词字符的位置。

The wordsArray.sort很重要,因为如果没有它,具有相同开头的较短单词可能会在较长单词出现之前“获胜”。

The .replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')必须在搜索词中转义特殊字符。

支持lookbehinds的JS环境的变体:

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, see demo https://regex101.com/r/4sg00q/1. Here, (?<!\w)负lookbehind 匹配前面没有紧接单词字符的位置。这也使得捕获组变得多余,我将其替换为非捕获组,(?:...),并且替换模式现在仅包含一个占位符,$&,插入整个匹配项。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅使用 SPAN 标签将可能以特殊字符开头或结尾且具有公共前缀的搜索短语包装为整个单词 的相关文章

随机推荐