我试图替换CSS文件中的所有类名。我正在使用JavaScript / Node.js.
我目前的解决方案是:/\.[a-z][a-z0-9-_]*/g
。
在文件的末尾是一个引用源映射文件的注释:/*# sourceMappingURL=style.css.map */
。现在,该URL的文件扩展名也将被替换。
给出以下输入:
.text-center { text-align: center; }
table.simple{background:#fff;}.bg-white{background:#fff;}
/*# sourceMappingURL=style.css.map */
/*
Example comment file.css
*/
结果是:
.a { text-align: center; }
table.a{background:#fff;}.a{background:#fff;}
/*# sourceMappingURL=style.a.a */
/*
Example comment file.a
*/
我想要的是:
.a { text-align: center; }
table.a{background:#fff;}.a{background:#fff;}
/*# sourceMappingURL=style.css.map */
/*
Example comment file.css
*/
我如何更改我的RegEx,以便它只匹配注释之外的类名(//
注释与此无关)?
答案 0 :(得分:2)
试试这个正则表达式:
\.[^{\s]*(?=\s*{)
并将每个匹配项替换为.a
<强> Click for Demo 强>
<强>解释强>
\.
- 匹配.
[^{\n]*
- 匹配任何既不是空格也不是{
(?=\s*{)
- 积极前瞻以确保当前位置后跟0 +空格后跟{
。现在,如果我们有格式
的注释,上面的正则表达式就会失败/*# sourceMappingURL=style.css.map {*/
,{
在评论中css.map
之后出现。因此,要处理这种情况,您可以使用以下正则表达式(几乎与之前的正则表达式相似。正则表达式的另一个负面预测)
\.[^{\s]*(?=\s*{)(?!(?:(?!\/\*)[\s\S])*\*\/)
<强> Click for Demo 强>
<强>解释强>
\.[^{\s]*(?=\s*{)
- 与之前的正则表达式相似(?!(?:(?!\/\*)[\s\S])*\*\/)
- 否定前瞻以确保.classname
形式的评论中不存在当前位置(/*...*/
后面的位置)
(?!....
- 负向前瞻(?:(?!\/\*)[\s\S])*
- tempered greedy token可以贪婪地匹配任何字符的0次出现,而不是以序列/*
\*\/
- 匹配*/
答案 1 :(得分:1)
这两种方法都适用于不同的情况,例如ids之间的类或选择中的多个类:
.class-a, #id-a, .class-b:hover {}
在第一种方法中,您可以匹配注释部分和CSS类,然后在匹配时替换类名并保留注释:
\/\*[\s\S]*?\*\/|(\.[a-z_-][\w-]*)(?=[^{}]*{)
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Match comments Match and capture classes
故障:
\/\*[\s\S]*?\*\/ # Match a comment block
| # Or
( # Start of capturing group #1
\.[a-z_-][\w-]* # Match a CSS class name
) # End of CG #1
(?= # Start of a positive lookahead
[^{}]*{ # Class should be followed by a `{` (may not be immediately)
) # End of lookahead
JS代码:
var str = `.text-center { text-align: center; }
table.simple{background:#fff;}.bg-white{background:#fff;}
/*# sourceMappingURL=style.css.map */
/*
Example comment file.css
*/`
console.log(str.replace(/\/\*[\s\S]*?\*\/|(\.[a-z_-][\w-]*)(?=[^{}]*{[^{}]*})/g,
function($0, $1) {
return $1 ? '.a' : $0; // If a class is matched ...
}
));
如果您在评论中没有想到这样的事件将会存在:
/* style.css {css file} */
您可以在第一种方法中省略匹配的评论:
\.[a-z_-][\w-]*(?=[^{}]*{[^{}]*})
^^^^^^^
Added for a more strict selection
JS代码:
var str = `.text-center { text-align: center; }
table.simple{background:#fff;}.bg-white{background:#fff;}
/*# sourceMappingURL=style.css.map */
/*
Example comment file.css
*/`
console.log(str.replace(/\.[a-z_-][\w-]*(?=[^{}]*{[^{}]*})/g, '.a'));
答案 2 :(得分:0)
我已经在 pcre flavor
中使用以下RegEx/(\/\*)?(?(1)(.*\*\/)|(\.[a-z][a-z0-9-_]*))/g
我正在使用条件语句。每当它检测到评论的开始时,它都不会查找类名,而是查找评论的结尾。但是,这不适用于多行评论。类名是第三个捕获组。因此,要替换类名,只需触摸包含捕获组3的匹配项。
我没注意到我在regex101.com上使用了pcre而不是javascript,最后在我的JS代码中出现了语法错误。我现在正在努力寻找适用于JS的解决方案。
编辑:
我现在把它移植到JS:
/(?=\/\*)|(\.[a-z][a-z0-9-_]*)(?!.*\*\/)/g
我仍然需要找到一种方法让它与多行一起使用。
答案 3 :(得分:-1)