我有一个搜索系统,将关键字拆分为块并在字符串中搜索它:
var regexp_school = new RegExp("(?=.*" + split_keywords[0] + ")(?=.*" + split_keywords[1] + ")(?=.*" + split_keywords[2] + ").*", "i");
我想修改它,以便我只在单词的开头搜索它。
例如,如果字符串是:
"Bbe be eb ebb beb"
关键字为:"be eb"
然后我只想点击"be ebb eb"
换句话说,我想将上面的正则表达式与这个结合起来:
var regexp_school = new RegExp("^" + split_keywords[0], "i");
但我不确定语法是什么样的。
我也使用split函数来分割关键字,但我不想设置长度,因为我不知道关键字字符串中有多少字。
split_keywords = school_keyword.split(" ", 3);
如果我退出3,它会有动态长度还是长度为1?我试过做
alert(split_keywords.lenght);
但没有得到理想的回应
答案 0 :(得分:2)
您应该使用特殊的word boundary字符\b
来匹配单词的开头。要为任意数量的关键字创建表达式,可以在循环中生成它。
var regex = '';
for(var i = split_keywords.length;i--; ) {
// two slashes are needed to insert `\` literally
regex += "(?=.*\\b" + split_keywords[i] + ")";
}
var regexp_school = new RegExp(regex, "i");
我不确定性能,但您也可以考虑使用indexOf
来测试子字符串是否包含在字符串中。
<强>更新强>
如果\b
对您不起作用(因为其他“特殊”字符),并且所有单词都用空格分隔,则可以使用
"(?=.*\\s" + split_keywords[i] + ")"
或
"(?=.* " + split_keywords[i] + ")"
但为了实现此目的,您必须使用空格预置您正在搜索的文字:
" " + textYouSearchIn
或者你写的是一个更复杂的表达式:
"(?=(^|.*\\s)" + split_keywords[i] + ")"
答案 1 :(得分:1)
几点。首先,您需要将正则表达式锚定到字符串的开头。否则,如果没有匹配,则在声明匹配失败之前,正则表达式引擎必须尝试组合的 LOT (实际上必须检查所有) 。其次,在拆分字符串时,使用/\s+/
而不是单个空格 - 这可以防止在结果数组中获得空匹配,以防任何关键字之间存在多个空格。第三,如果是关键字数组中的空字符串,则不希望将它们添加到正则表达式中。 Felix的解决方案非常接近标记,但是一旦所有正向前瞻断言完成,它实际上并不匹配字符串。也就是说,这是我提出的解决方案:
var split_keywords = school_keyword.split(/\s+/);
var regex = "^"; // Anchor to start of string.
for (var i = 0, len = split_keywords.length; i < len; ++i) {
if (split_keywords[i]) { // Skip empty keyword strings.
regex += "(?=.*?\\b" + split_keywords[i] + ")";
}
}
regex += ".*$"; // Add ending to actually match the line.
var regexp_school = new RegExp(regex, "i");
我也把贪婪的量词变成了懒惰。这是适用的一种情况。