2015-09-28 152 views
2

我有一个包含多个句子的字符串。我也有当前的光标/插入符号位置。通过光标/光标位置获取当前语句

我需要能够在给定的光标位置提取当前语句。

例如,借此字符串:

This is the first sentence. And this is the second! Finally, this is the third sentence

如果当前光标位置是33则光标处于所述第二句子。

在这种情况下,返回结果应该是:

And this is the second!

我只需要使用的.?!

任何帮助,这将不胜感激标准一句定义者。

尽管我期待需要正则表达式,但如果使用本机方法有更快的选择,我也会对此感兴趣。

+0

只需按'。?!'分割并添加长度,直到获得长度> =当前位置。 – ndn

+0

试试[这个演示](http://jsfiddle.net/qqzssoyv/) - 它是你在找什么? –

+0

@stribizhev完美......我也觉得有点愚蠢,因为没有意识到解决方案一开始就有多简单。无论如何,如果你想将它写成答案,我会奖励给你。 – Gordo

回答

1

这是一种实现你所需要的方法:使用String#split/[?!.]/g来获取一组语句,然后遍历数组以总结找到的句子的长度,并且如果索引小于计数,返回句子。

function getSentenceByPos(idx, str) { 
 
    pos = 0; 
 
    array = str.split(/[?!.]/g); 
 
    for (var i=0; i<array.length; i++) { 
 
    \t \t pos += array[i].length + 1; 
 
     if (pos >= idx) { 
 
      return array[i]; 
 
     } 
 
\t } 
 
}// 26 still 1 then `.`. 51 then `!` - 53 is 3rd sentence! 
 
document.write(getSentenceByPos(53, "This is the first sentence. And this is the second! Finally, this is the third sentence"));

+0

但是你正在从短语中删除分隔符时进行拆分..这将工作与光标刚刚超过一个分隔符? – Amarnasan

+0

@Amarnasan:我明白你的观点。所以,实际上,迭代时应该增加'pos'。 'pos + = array [i] .length + 1;'修复它。 –

+0

-1在数组上使用'for..in'。 ** ['for ... in'不保证](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Array_iteration_and_for...in )元素在**上迭代的顺序。这段代码依赖于它的顺序迭代。 –

0

此功能将尊重这些习语的限制光标(像!.

function getPhrase(string, cursor) { 
    phrases = string.match(/.*?(!|\.|$)/g) 
    basecursor = 0; 
    phrase = phrases[0] 
    for(ii=0; ii<phrases.length-1; ii++) { 
     if (basecursor+phrases[ii].length<cursor) { 
      phrase = phrases[ii+1] 
      basecursor += phrases[ii].length 
     } 
    } 
    return(phrase) 
} 
string = "This is the first sentence. And this is the second! Finally, this is the third sentence" 
cursor = 0 
phrase = getPhrase(string, cursor) 
document.write(phrase) 
+0

仅供参考:'。*?(!| \。| $)'不支持'?'作为句子结尾。然后,分割“[?!。]'比延迟匹配更快。此外,'。*?'不会匹配换行符(这可能与此无关)。而另一种宠物便是:当你使用替换时,回溯比没有回溯的多,尽管用你的方法,你必须使用替换。否则,一个不错的选择。 –

1

我想补充一点,不使用正则表达式的答案分割 字符串,因为这样做效率很低,并且可能会在较大的文本块上非常缓慢。

最有效的方法可能是使用几个循环进行搜索,只需要2遍就可以找到句子的结尾。

var sentenceFromPos = function (s, pos) { 
    var len = s.length, 
    start, 
    end, 
    char; 

    start = pos; 
    end = pos; 

    while (start >= 0) { 
    char = s.charAt(start); 
    if (char === '.' || char === '?' || char === '!') { 
     break; 
    } 
    start -= 1; 
    } 

    while (end < len) { 
    char = s.charAt(end); 
    if (char === '.' || char === '?' || char === '!') { 
     break; 
    } 
    end += 1; 
    } 

    return s.substring(start + 1, end + 1).trim(); 
}; 

var phrase = 'This is the first sentence. And this is the second! Finally, this is the third sentence'; 

console.log(sentenceFromPos(phrase, 10)); 
console.log(sentenceFromPos(phrase, 33)); 
console.log(sentenceFromPos(phrase, 53));