我正在使用jlinq从一些 json 返回搜索结果,我想向用户显示包含搜索词的结果文本片段,在搜索词之前说三个词,在搜索词之后说三个词。
var searchTerm = 'rain'
var text = "I'm singing in the rain, just singing in the rain";
结果会是“在雨中唱歌,只是在唱歌”
我怎么能在javascript中做到这一点?我已经看到了一些使用 php 的建议,但没有专门针对 javascript 的建议。
我正在使用jlinq从一些 json 返回搜索结果,我想向用户显示包含搜索词的结果文本片段,在搜索词之前说三个词,在搜索词之后说三个词。
var searchTerm = 'rain'
var text = "I'm singing in the rain, just singing in the rain";
结果会是“在雨中唱歌,只是在唱歌”
我怎么能在javascript中做到这一点?我已经看到了一些使用 php 的建议,但没有专门针对 javascript 的建议。
这是一个稍微好一点的近似值:
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)
}
唯一可能的问题是,当它抓取您的模式的第一次出现时,它会切掉匹配的部分,然后再次搜索。您还需要注意“短语”变量中没有任何正则表达式字符(或将其转换为十六进制或八进制表示)
无论如何,我希望这对人有所帮助!:)
首先,我们需要在字符串中找到第一次出现的术语。相反,我们处理的是一个单词数组,所以我们最好在这样的数组中找到第一次出现的词。我决定将此方法附加到 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'