2010-08-04 22 views
56

我試圖找到所有出現的字符串在另一個字符串中的位置,不區分大小寫。如何在JavaScript中查找另一個字符串中所有出現的索引?

例如,給定的字符串:

I learned to play the Ukulele in Lebanon.

和搜索字符串le,我想獲得數組:

[2, 25, 27, 33] 

兩個字符串將是變量 - 即,我不能硬編碼它們的值。

我覺得這對於正則表達式來說是一件容易的事情,但經過一段時間的努力找到一個可行的工作之後,我一直沒有運氣。

我發現this example如何使用.indexOf()完成此操作,但肯定必須有一個更簡潔的方法來做到這一點?

+2

+1爲黎巴嫩參考。 – astazed 2012-10-08 20:01:27

回答

102
var str = "I learned to play the Ukulele in Lebanon." 
var regex = /le/gi, result, indices = []; 
while ((result = regex.exec(str))) { 
    indices.push(result.index); 
} 

UPDATE

我沒能在原來的問題,搜索字符串需要一個變量來發現。我寫了另一個版本來處理這個使用indexOf的案例,所以你回到了你開始的地方。正如Wrikken在評論中指出的那樣,爲了使用正則表達式來處理常規情況,您需要轉義特殊的正則表達式字符,此時我認爲正則表達式解決方案變得比它的價值更令人頭疼。

function getIndicesOf(searchStr, str, caseSensitive) { 
 
    var searchStrLen = searchStr.length; 
 
    if (searchStrLen == 0) { 
 
     return []; 
 
    } 
 
    var startIndex = 0, index, indices = []; 
 
    if (!caseSensitive) { 
 
     str = str.toLowerCase(); 
 
     searchStr = searchStr.toLowerCase(); 
 
    } 
 
    while ((index = str.indexOf(searchStr, startIndex)) > -1) { 
 
     indices.push(index); 
 
     startIndex = index + searchStrLen; 
 
    } 
 
    return indices; 
 
} 
 

 
var indices = getIndicesOf("le", "I learned to play the Ukulele in Lebanon."); 
 

 
document.getElementById("output").innerHTML = indices + "";
<div id="output"></div>

+0

這裏'le'是一個變量字符串?即使使用'新的Regexp(str)',特殊字符的危險也在潛伏,比如搜索$ 2.50。像'regex = new Regexp(dynamicstring.replace(/([\\。+ *?\\ [^ \\] $(){} =!<> |:])/ g,'\\ $ 1') );'會更接近恕我直言。我不確定js是否有內置的正則表達式轉義機制。 – Wrikken 2010-08-04 23:35:16

+0

'新的RegExp(searchStr)'將是方式,是的,在一般情況下,你將不得不逃避特殊字符。除非你需要這種普遍性,否則這並不值得。 – 2010-08-04 23:43:33

+0

......我看到:我沒有發現OP的確需要這種普遍性的問題。重寫... – 2010-08-04 23:45:52

10
 
function indexes(source, find) { 
    var result = []; 
    for (i = 0; i < source.length; ++i) { 
    // If you want to search case insensitive use 
    // if (source.substring(i, i + find.length).toLowerCase() == find) { 
    if (source.substring(i, i + find.length) == find) { 
     result.push(i); 
    } 
    } 
    return result; 
} 

indexes("I learned to play the Ukulele in Lebanon.", "le") 

+2

+1免RegEx-free解決方案。 – chryss 2010-08-04 23:34:25

+0

謝謝,jcubic - 這看起來是一個很好的解決方案。 – Bungle 2010-08-05 00:41:06

+4

+1。我運行了一些測試用於比較使用Regex的解決方案。最快的方法是使用正則表達式:http://jsperf.com/javascript-find-all – StuR 2013-05-08 11:11:10

8

你當然可以做到這一點!

//make a regular expression out of your needle 
var needle = 'le' 
var re = new RegExp(needle,'gi'); 
var haystack = 'I learned to play the Ukulele'; 

var results = new Array();//this is the results you want 
while (re.exec(haystack)){ 
    results.push(re.lastIndex); 
} 

編輯:學會拼寫正則表達式

而且,我意識到這不是正是你想要什麼,因爲lastIndex告訴我們針不是開始的結束,但它很接近 - 你可以推re.lastIndex-needle.length到結果數組...

編輯:添加鏈接

@Tim Down的答案使用了RegExp.exec()的結果對象,並且我所有的Javascript資源都使用它(除了給你匹配的字符串外)。所以當他使用result.index時,這是某種未命名的匹配對象。在MDC description of exec中,他們實際上對這個對象進行了詳細的描述。

+0

Annnd @Tim Down有贏家,不理我... – Ryley 2010-08-04 23:09:41

+0

哈!謝謝你的貢獻,無論如何 - 我很感激! – Bungle 2010-08-05 00:39:55

-1
function countInString(searchFor,searchIn){ 

var results=0; 
var a=searchIn.indexOf(searchFor) 

while(a!=-1){ 
    searchIn=searchIn.slice(a*1+searchFor.length); 
    results++; 
    a=searchIn.indexOf(searchFor); 
} 

return results; 

} 
-1

下面的代碼將做的工作適合你:

function indexes(source, find) { 
    var result = []; 
    for(i=0;i<str.length; ++i) { 
    // If you want to search case insensitive use 
    // if (source.substring(i, i + find.length).toLowerCase() == find) { 
    if (source.substring(i, i + find.length) == find) { 
     result.push(i); 
    } 
    } 
    return result; 
} 

indexes("hello, how are you", "ar") 
3

使用String.prototype.match

下面是從MDN文檔本身就是一個例子:

var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 
var regexp = /[A-E]/gi; 
var matches_array = str.match(regexp); 

console.log(matches_array); 
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e'] 
+0

這很簡單。 – igaurav 2017-11-21 11:27:11

+4

問題是如何找到*索引*的事件,而不是它們自己的事件! – Luckylooke 2017-11-23 11:32:52

1

如果你只是想找到我想你指向一個小黑客所有匹配的位置:

haystack = 'I learned to play the Ukulele in Lebanon.' 
needle = 'le' 
splitOnFound = haystack.split(needle).map(function (culm) { 
    return this.pos += culm.length + needle.length 
}, {pos: -needle.length}).slice(0, -1) 

如果你有一個可變長度的RegExp,它可能不適用,但對於某些可能有用的。

相關問題