我正在尝试编写一个Javascript函数来查找文本文档中所有单词出现的索引。目前这就是我所拥有的 -
//function that finds all occurrences of string 'needle' in string 'haystack'
function getMatches(haystack, needle) {
if(needle && haystack){
var matches=[], ind=0, l=needle.length;
var t = haystack.toLowerCase();
var n = needle.toLowerCase();
while (true) {
ind = t.indexOf(n, ind);
if (ind == -1) break;
matches.push(ind);
ind += l;
}
return matches;
}
但是,这给了我一个问题,因为这与单词的出现相匹配,即使它是字符串的一部分。例如,如果针是“书”而干草堆是“汤姆写了一本书。这本书的名字是Facebook的傻瓜”,结果是“书”,“书”和“Facebook”的索引,当我只想要时'book'的索引。我怎么能做到这一点?任何帮助表示赞赏。
答案 0 :(得分:2)
这是我建议的正则表达式:
/\bbook\b((?!\W(?=\w))|(?=\s))/gi
解决您的问题。使用exec()
方法尝试一下。我提供的正则表达式还会考虑您提供的示例句中出现的“小册子”等字样:
function getMatches(needle, haystack) {
var myRe = new RegExp("\\b" + needle + "\\b((?!\\W(?=\\w))|(?=\\s))", "gi"),
myArray, myResult = [];
while ((myArray = myRe.exec(haystack)) !== null) {
myResult.push(myArray.index);
}
return myResult;
}
修改
我已经编辑了正则表达式来解释像“小册子”这样的单词。我也将我的答案重新格式化为与你的功能类似。
您可以进行一些测试here
答案 1 :(得分:1)
试试这个:
function getMatches(searchStr, str) {
var ind = 0, searchStrL = searchStr.length;
var index, matches = [];
str = str.toLowerCase();
searchStr = searchStr.toLowerCase();
while ((index = str.indexOf(searchStr, ind)) > -1) {
matches.push(index);
ind = index + searchStrL;
}
return matches;
}
indexOf
返回第一次出现的书的位置。
var str = "Tom wrote a book. The book's name is Facebook for dummies";
var n = str.indexOf("book");
答案 2 :(得分:0)
我不知道那里发生了什么,但我可以使用正则表达式提供更好的解决方案。
function getMatches(haystack, needle) {
var regex = new RegExp(needle.toLowerCase(), 'g'),
result = [];
haystack = haystack.toLowerCase();
while ((match = regex.exec(haystack)) != null) {
result.push(match.index);
}
return result;
}
用法:
getMatches('hello hi hello hi hi hi hello hi hello john hi hi', 'hi');
Result => [6, 15, 18, 21, 30, 44, 47]
保留book
vs books
问题,您只需要为"book "
提供空格。
或者你可以做的功能。
needle = ' ' + needle + ' ';