2012-04-14 38 views
6

我有一個非常漂亮的工具,underscore-cli,打印出幫助/用法信息時是越來越奇怪的行爲。在匹配行首時,JavaScript V8正則表達式引擎中的錯誤?

在使用()函數,我這樣做是爲了文本縮進塊(例如,選項):

str.replace(/^/, " "); 

此正則表達式,除了是很明顯的,當屬直出的TJ Hollowaychuk的​​碼。正則表達式是正確的。

然而,我得到插進我的使用文本中間空間的bizzare。像這樣:

 Commands: 
... 
    values    Retrieve all the values of an object's properties. 
    extend &ltobject>  Override properties in the input data. 
    defaults &ltobject> Fill in missing properties in the input data. 
    any &ltexp>   Return 'true' if any of the values in the input make the expression true. Expression args: (value, key, list) 
     all &ltexp>   Return 'true' if all values in the input make the expression true. Expression args: (value, key, list) 
    isObject   Return 'true' if the input data is an object with named properties 
    isArray    Return 'true' if the input data is an array 
    isString   Return 'true' if the input data is a string 
... 

99%的機會,這已經是在V8中的錯誤。

任何人都知道爲什麼會這樣,還是最簡單的變通辦法會是什麼?

是的,結果是這個IS一個V8的錯誤,1748是確切的。下面是the workaround I used in the tool

str.replace(/(^|\n), "$1 "); 
+0

只需在開頭添加一個字符串? – 2012-04-14 01:06:53

+1

你有沒有清理回車的文字? – Trey 2012-04-14 01:13:26

+0

你有沒有試過把空間以外的東西?瀏覽器不設於顯示多個空間 - 爲了把你需要使用'       '... – 2012-04-14 01:18:59

回答

4

這是V8中的錯誤(錯誤1748):

http://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/regress/regress-1748.js?spec=svn9504&r=9504

這裏是錯誤的測試:

function assertEquals(a, b, msg) { if(a !== b) { console.log("'%s' != '%s' %s", a, b, msg); } } 

var str = Array(10000).join("X"); 
str.replace(/^|X/g, function(m, i, s) { 
    if (i > 0) assertEquals("X", m, "at position 0x" + i.toString(16)); 
}); 

在我的盒子,它打印:

'X' != ''. at position 0x100 
'X' != ''. at position 0x200 
'X' != ''. at position 0x300 
'X' != ''. at position 0x400 
'X' != ''. at position 0x500 
'X' != ''. at position 0x600 
... 

上的jsfiddle,不打印輸出(V8版本在我的Chrome瀏覽器沒有按」噸有錯誤):

http://jsfiddle.net/PqDHk/


錯誤歷史:

V8 changelog,該錯誤是固定在V8-3.6.5(2011-10-05)。

Node.js changelog,節點0.6.5應該使用V8-3.6.6.11!?!?。 Node.js從V8-3.6.4更新爲V8-3.7.0(Node-0.5.10),然後降級到Node-0.6.0的V8-3.6.6。所以從理論上講,這個bug在節點V0.6.0之前應該已經修復了。爲什麼它仍然在Node-0.6.5上重現?奇。

有人能與最新的(節點0.6.15)運行測試片段上方,如果它產生的錯誤報告?或者我會最終解決它。

感謝ZachB,用於確認對節點0.6.15這個bug。我提交的問題(issue #3168)對節點和修復(5d69bbf)已被應用,並應包括在節點0.6.16。 :) :) :)

在此之前,解決方法是更換:

str.replace(/^/, indent); 

有了:

str.replace(/(^|\n)/, "$1" + indent); 

更新:只是爲了笑聲,我檢查這個對當前節點版本, v0.8.1,並確認該錯誤確實已修復。我沒有反省過,並確認錯誤是否在0.6.16或v0.8.X系列之間的某個時間被修復。

+1

v0.6.15打印相同的''X'!=''。在位置0x ...'位爲我。 – ZachB 2012-04-23 05:53:24

+0

感謝您對Zach進行測試。看起來bug仍然存在。我將在Node上提出問題。 – 2012-04-24 03:15:17

+0

https://github.com/joyent/node/issues/3168 – 2012-04-24 03:24:05

1

解決方法:捕獲的第一個字符,並用空格代替它,和它本身

str.replace(/^./, " $1"); 

,或者以確保該行沒有縮進

str.replace(/^[^\s]/, " $1"); 
+0

試過(捕獲第一個字符)。事實證明它不起作用。 +1雖然努力。 – 2012-04-14 01:17:31

+0

好拍。張貼小提琴,我很樂意再次刺傷它。 – Umbrella 2012-04-14 01:20:03

+2

@ddopson:'$ 1'適用於捕獲組。 'str.replace(/^(.)/ gm,'$ 1');'http://jsfiddle.net/T2Uur/ – 2012-04-14 03:00:02