使用正则表达式查找不在注释内的CSS类名

使用正则表达式查找不在注释内的CSS类名,css,regex,class,comments,Css,Regex,Class,Comments,我正在尝试替换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;}

我正在尝试替换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
*/

如何更改我的正则表达式,使其只匹配注释之外的类名(
/
注释在此处不相关)?

使用以下正则表达式,您应该能够从css文件中提取注释中未包含的所有类名。 类名以点(.)开头很重要

正则表达式:

/^.[a-z][a-z0-9-_].*?[\s]/mg

我已经在pcre flavor中使用了以下正则表达式

/(\/\*)?(?(1)(.*\*\/)|(\.[a-z][a-z0-9-_]*))/g
我使用的是条件语句。每当它检测到注释的开头时,它不会查找类名,而是查找注释的结尾。但是,这不适用于多行注释。类名是第三个捕获组。因此,要替换类名,只需触摸包含捕获组3的匹配项

我没有注意到我在上使用了pcre而不是javascript,结果在我的JS代码中出现了语法错误。我现在正在寻找一个适合JS的解决方案

编辑:

我现在将其移植到JS:

/(?=\/\*)|(\.[a-z][a-z0-9-_]*)(?!.*\*\/)/g
我仍然需要找到一种方法使它能够与多行一起工作。试试这个正则表达式:

\.[^{\s]*(?=\s*{)
并将每个匹配项替换为
.a

说明:

  • \.
    -匹配
  • [^{\n]*
    -匹配任何既不是空格也不是
    {
  • (?=\s*{)
    -正向前瞻,以确保当前位置后跟0+空格,后跟
    {

现在,如果我们对格式有意见,上面的正则表达式将失败

/*# sourceMappingURL=style.css.map {*/
i、 e,
{
出现在注释中的
css.map
之后。因此,要处理这种情况,可以使用下面的正则表达式(几乎类似于前面的正则表达式。只需对正则表达式进行一次负向前瞻)

说明:

  • \.[^{\s]*(?=\s*{)
    -类似于前面的正则表达式
  • (?!(?:(?!\/\*)[\s\s])*\*/)
    -负向前看,以确保当前位置(位于
    .classname
    后面的位置)不存在于表单
    /*…*/
    的注释中
    • (?!…
      -负前瞻
    • (?:(?!\/\*)[\s\s])*
      -贪婪地匹配任何字符的0+次出现次数,而不是以序列开始
      /*
    • \*\/
      -匹配
      */
这两种方法在不同的情况下工作,如ID之间的类或选择中的多个类:


第一种方法 在第一种方法中,您可以匹配comment section和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;}
表.simple{background:#fff;}.bg white{background:#fff;}
/*#sourceMappingURL=style.css.map*/
/*
示例comment file.css
*/`
console.log(str.replace(/\/\*[\s\s]*?\*\/\/\*(\.[a-z\][\w-]*)(?=[^{}]*{[^{}]*})/g,
函数($0,$1){
返回$1?'.a':$0;//如果类匹配。。。
}

))
您使用的是哪种正则表达式引擎/语言?我使用的是JavaScript/Node.js@ctwheels。正则表达式中的第一个点不代表点。您的意思是
\.
而不是
^。
这对我不起作用,因为我也在处理小型化的代码。例如:
p.text-center{}.text-center{}
这不适用于具有多个类的选择器。我在问题中没有指定这一点。
\/\*[\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