4

我正在使用jlinq从一些 json 返回搜索结果,我想向用户显示包含搜索词的结果文本片段,在搜索词之前说三个词,在搜索词之后说三个词。

var searchTerm = 'rain'
var text = "I'm singing in the rain, just singing in the rain";

结果会是“在雨中唱歌,只是在唱歌”

我怎么能在javascript中做到这一点?我已经看到了一些使用 php 的建议,但没有专门针对 javascript 的建议。

4

2 回答 2

5

这是一个稍微好一点的近似值:

function getMatch(string, term)
{
    index = string.indexOf(term)
    if(index >= 0)
    {
        var _ws = [" ","\t"]

        var whitespace = 0
        var rightLimit = 0
        var leftLimit = 0

        // right trim index
        for(rightLimit = index + term.length; whitespace < 4; rightLimit++)
        {
            if(rightLimit >= string.length){break}
            if(_ws.indexOf(string.charAt(rightLimit)) >= 0){whitespace += 1}
        }

        whitespace = 0
        // left trim index
        for(leftLimit = index; whitespace < 4; leftLimit--)
        {
            if(leftLimit < 0){break}
            if(_ws.indexOf(string.charAt(leftLimit)) >= 0){whitespace += 1}
        }
        return string.substr(leftLimit + 1, rightLimit) // return match
    }
    return // return nothing
}

这有点“贪婪”,呵呵,但它应该可以解决问题。注意 _ws 数组。您可以包含您喜欢的所有空格或修改以使用正则表达式来检查空格。

这已被稍微修改以处理短语。它只找到该术语的第一次出现。处理多个事件需要稍微不同的策略。

在我看来,您想要的也可能(在不同程度上)通过以下方式:

function snippet(stringToSearch, phrase)
{
    var regExp = eval("/(\\S+\\s){0,3}\\S*" + phrase + "\\S*(\\s\\S+){0,3}/g")
    // returns an array containing all matches
    return stringToSearch.match(regExp)
}  

唯一可能的问题是,当它抓取您的模式的第一次出现时,它会切掉匹配的部分,然后再次搜索。您还需要注意“短语”变量中没有任何正则表达式字符(或将其转换为十六进制或八进制表示)

无论如何,我希望这对人有所帮助!:)

于 2013-04-23T03:42:15.533 回答
2

首先,我们需要在字符串中找到第一次出现的术语。相反,我们处理的是一个单词数组,所以我们最好在这样的数组中找到第一次出现的词。我决定将此方法附加到 Array 的原型中。我们可以使用indexOf,但是如果我们用 " " 分割一个字符串,我们将处理像 "rain" 这样的词,并且indexOf不会匹配它。

Array.prototype.firstOccurance = function(term) { 
    for (i in this) { 
        if (this[i].indexOf(term) != -1 ) {  // still can use idnexOf on a string, right? :)
            return parseInt(i,10);  // we need an integer, not a string as i is
        }
    }
}

然后,我按单词拆分字符串,为此,将其拆分为“”:

function getExcerpt(text, searchTerm, precision) {
    var words = text.split(" "),
        index = words.firstOccurance(searchTerm),
        result = [], // resulting array that we will join back
        startIndex, stopIndex;
    // now we need first <precision> words before and after searchTerm
    // we can use slice for this matter
    // but we need to know what is our startIndex and stopIndex
    // since simple substitution from index could lead us to 
    // a negative value
    // and adding to an index could get us to exceeding words array length

    startIndex = index - precision;
    if (startIndex < 0) {
        startIndex = 0;
    }

    stopIndex = index + precision + 1;
    if (stopIndex > words.length) {
        stopIndex = words.length;
    }


    result = result.concat( words.slice(startIndex, index) );
    result = result.concat( words.slice(index, stopIndex) );
    return result.join(' '); // join back
}

结果:

> getExcerpt("I'm singing in the rain, just singing in the rain", 'rain', 3)
'singing in the rain, just singing in'


> getExcerpt("I'm singing in the rain, just singing in the rain", 'rain', 2)
'in the rain, just singing'


> getExcerpt("I'm singing in the rain, just singing in the rain", 'rain', 10)
'I\'m singing in the rain, just singing in the rain'
于 2013-04-23T04:21:01.523 回答