我正在尝试根据用户的输入但使用原始拼写实现搜索结果的粗体部分。 我想避免点、多个空格、破折号,并使其不区分大小写。
例如,我有一个简单的搜索结果:Al. Jana
.
我正在尝试粗体搜索部分,因此:
当用户键入al
时,我想显示 ->Al。贾娜
Al
->贾娜
AL
->阿尔.贾娜
al jana
->阿尔·贾纳
jana
-> 阿尔·贾纳
Al. Jana
->阿尔·贾纳
或者,如果我们有一个搜索结果Al. Jana Something - More
并且用户键入something more
它应该返回:Al.Jana 某事 - 更多。
到目前为止,我编写了以下代码:
function modify(result, query) {
let re = new RegExp(query, 'ig');
return result.replace(/- /g, "").replace(/./g, "").replace(re, '<b>' + query + '</b>'); //replacing "- " as dash is always surrounded with spaces so it trims one unnecessary space; is there a better way to make "inside-trim"?
}
let bolded = modify("Al. Jana", "al jana");
console.log(bolded);
小提琴:https://jsfiddle.net/ayb8Lj4r/
但这不是我想要实现的目标。也许我应该大量使用.indexOf
?我不确定。
您需要在搜索查询的所有单个字符之间添加[-s.]*
模式。这将允许字符之间任意数量的空格、-
或.
字符。如果要允许任何非单词字符,则可以改用W*
。
此外,您应该转义所有特殊字符,否则,如果查询包含像(
或+
这样的字符,结果将不会符合预期。
这是固定的代码片段:
function modify(result, query) {
var re = new RegExp(query.split("").map(function(x) {
return x.replace(/[-/\^$*+?.()|[]{}]/g, '\$&');
}).join("[-\s.]*"), 'ig');
return result.replace(re, '<b>$&</b>');
}
var bolded = modify("Al. Jana Something - More", "al jana");
document.querySelector("#result").innerHTML = bolded;
<div id="result"/>
答案
要获得所需的结果,您可以利用捕获组和变量。
let re = new RegExp('(' + query + ')', 'ig');
这允许您在replace
函数的第二个参数中使用$1
来指向匹配的文本,因为它在原始字符串中的大小写。
return result.replace(/- /g, "")
.replace(/./g, "")
.replace(re, '<b>$1</b>');
最后,要用al. jana
替换al jana
,我们可以进行额外的替换。
query = query.replace(/(al) (jana)/ig, "$1. $2");
并删除您的经期更换
.replace(/./g, "")
由于我们也想要连字符,因此根据您的评论,我们也可以删除该行
.replace(/- /g, "")
我们只剩下:
function modify(result, query) {
query = query.replace(/(al) (jana)/ig, "$1. $2");
let re = new RegExp('(' + query + ')', 'ig');
return result.replace(re, '<b>$1</b>');
}
例
function modify(result, query) {
query = query.replace(/(al) (jana)/ig, "$1. $2");
let re = new RegExp('(' + query + ')', 'ig');
return result.replace(re, '<b>$1</b>');
}
let bolded = modify("Al. Jana Something - More", "al jana");
document.querySelector("#result").innerHTML = bolded;
<div id="result">
</div>