2017-06-19 53 views
2

我的目標:
我試圖解析CSS串檢索如CSS規則,進口的意見,不同的部分...的Javascript正則表達式替換 - 隨機數出現

我做了什麼:
我的函數從檢索註釋開始,然後檢索導入並最終檢索規則塊。
一旦檢索到這些部件,就會將每個部件記錄到控制檯。

我的問題:
我的問題是,當我測試了一下,似乎是在規則塊部分被記錄到控制檯我的代碼生成隨機數。

我的代碼:

function output(css) { 
 
    if(typeof css === 'string') { 
 
     var current = css; 
 
     // remove comments 
 
     var comments = []; 
 
     current = current.replace(/\s*\/\*[^*]*\*+([^/*][^*]*\*+)*\/|^\/\/[^\n]*\n?/gim, c=>comments.push(c.trim())); 
 

 
     // retrieve @ imports 
 
     var imports = []; 
 
     current = current.replace(/@[^;{]+;/gi, imp => imports.push(imp.trim())); 
 

 
     // retrieve rules blocks 
 
     var rulesBlocks = []; 
 
     current = current.replace(/[^};]+{[^{]*}/gi, block => { 
 
      rulesBlocks.push(block.trim()); 
 
     }); 
 
     console.log(comments, imports, rulesBlocks); 
 
    } 
 
} 
 

 
var css = document.getElementById('css').innerText; 
 

 
output(css);
<pre id="css"><code> 
 
#id, .class { 
 
\t #id { 
 
\t } 
 
} 
 
/** 
 
*/ 
 
@import url('http://www.test.com/test.min.js/'); 
 
/* 
 
@import url('http://www.test.com/test.min.js/'); 
 
*/ 
 
/***/ 
 
//#id, .class { 
 
#id, .class { 
 
\t #id { 
 
\t \t & { 
 
\t \t } 
 
\t } 
 
} 
 
#id, .class { 
 
\t #id { 
 
\t } 
 
} 
 
declaration { 
 
    data: test; 
 
} 
 
declaration2 declaration { 
 
    data 
 
} 
 

 
@font-face { 
 
    font-family: myFirstFont; 
 
    src: url(sansation_light.woff); 
 
} 
 
@font-face { 
 
    font-family: myFirstFont; 
 
    src: url(sansation_light.woff); 
 
} 
 
</code></pre>

正如你可以看到,如果你運行它,控制檯顯示在此行中的隨機數:
"1\n123\n4#id, .class {\n\t#id {\n\t\t& {\n\t\t}\n\t}\n}"
爲什麼它產生隨機數?爲什麼控制檯顯示1,123和4?

+1

這是因爲'Array.push()'方法返回數組的長度,您的替換正在做它。您可以在推送方法後添加'',然後按預期工作。 –

+1

不要使用正則表達式解析CSS。使用CSS解析器。 – 2017-06-19 17:20:37

+1

@torazaburo爲什麼我應該使用CSS解析器而不是正則表達式?什麼是CSS解析器? – DrunkenPoney

回答

2

由於數組push返回數組的新長度,並且您使用該返回值作爲replacement

您可以指定一個函數作爲第二個參數。在這種情況下,該函數將在匹配執行後被調用。該函數的結果(返回值)將被用作替換字符串。

所以:

current = current.replace(/@[^;{]+;/gi, imp => imports.push(imp.trim()));

將與imports新長度替換表達的每一個實例。

如果你想避免這個問題,你可以在推送後添加&&'';或替換函數中只有return imp(等)的註釋中使用Washington Guedes的建議,或者重寫函數以使用更習慣exec方法。