2012-09-10 26 views
1

正則表達式匹配是有功能的,其工作爲:是否有任何JavaScript函數,它不從指定索引

var regex=/\s*(\w+)/; 
var s="abc def "; 
var m1=regex.exec(s,0); // -> matches "abc" 
var m2=regex.exec(s,3); // -> matches "def" 

我知道另一種方法是:

var regex=/\s*(\w+)/; 
var s="abc def "; 
var m1=regex.exec(s); // -> matches "abc" 
var m2=regex.exec(s.substring(3)); // -> matches " def" 

但是我擔心如果s非常長,並且s.substring被多次調用,有些實現可能會以多次複製長字符串的效率不佳的方式工作。

+2

你可以把'。{3}'放在正則表達式的開頭。 – Pointy

+0

我假設你知道,在這種情況下,你可以開火'\ w +',然後走每個單獨的比賽?我猜這是減少你的實際情況,儘管... –

+0

如何分析你的代碼?或者看一下JavaScript虛擬機的實現? JavaScript中的字符串是不可變的,所以一個好的實現將爲字符共享空間而不是複製它們。所以是的,'substring'產生一個新的對象,但是不必複製字符數據。你的字符串的長度可能無關緊要。無論如何,爲了確保你在這裏沒有X-Y問題,考慮使用'g'標誌,因爲你可能試圖一遍又一遍地找出單詞,對吧? –

回答

4

是的,你可以在一個特定的指數使exec開始,如果正則表達式有g全局修改器。

var regex=/\s*(\w+)/g; // give it the "g" modifier 

regex.lastIndex = 3; // set the .lastIndex property to the starting index 

var s="abc def "; 

var m2=regex.exec(s); // -> matches "def" 

如果你的第一個代碼示例有g修改,那麼它會爲你寫的,上面同樣的原因,工作。使用g時,它會自動將.lastIndex設置爲上次匹配結束後的索引,因此下一次調用將從此處開始。

所以這取決於你需要什麼。

如果您不知道會有多少匹配,那麼通常的做法是在循環中運行exec

​​

或作爲do-while

var match, 
    regex = /\s*(\w+)/g, 
    s = "abc def "; 

do { 
    match = regex.exec(s); 
    if (match) 
     alert(match); 
} while(match); 
+2

+1一個不錯的有用答案,提醒人們'g',這可能是OP _wants_做事情的方式。 :) –

+0

謝謝。這就是我想要做的! – hoge1e3

+0

@ hoge1e3:不客氣。而且我改變了我的措辭,因爲我想起初我被誤解了。如果最終需要字符串中的所有匹配項,則不需要手動設置'.lastIndex'。你只是喜歡你的第一個例子,但包括'g'。或者你可以在循環中運行'exec'。我將用循環示例進行更新。 –

0

我不認爲有任何可以做到這一點的正則表達式方法。如果你擔心的表現,我也只是保存完整的字符串和剪斷繩子,讓substring只會被調用一次:

var regex=/\s*(\w+)/; 
var s="abc def "; 
var shorts = s.substring(3); 
var m1=regex.exec(s); // -> matches "abc" 
var m2=regex.exec(shorts); // -> matches " def" 
相關問題