2017-06-19 54 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方法。