2015-09-28 142 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));