【问题标题】:Find CSS class names that are not inside comments using Regular Expressions使用正则表达式查找不在注释内的 CSS 类名
【发布时间】:2018-07-23 01:46:29
【问题描述】:

我正在尝试替换 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,使其仅匹配 cmets 之外的类名(// cmets 与此无关)?

【问题讨论】:

  • 您使用的是哪种正则表达式引擎/语言?
  • 我正在使用 JavaScript/Node.js @ctwheels。

标签: css regex class comments


【解决方案1】:

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

正则表达式:

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

【讨论】:

  • 正则表达式中的第一个点不代表点。你的意思是\. 而不是^.
  • 这对我不起作用,因为我也在处理缩小代码。示例:p.text-center{}.text-center{}
【解决方案2】:

我已经让它在 pcre 风味

中与以下 RegEx 一起使用
/(\/\*)?(?(1)(.*\*\/)|(\.[a-z][a-z0-9-_]*))/g

我正在使用条件语句。每当它检测到注释的开头时,它不会查找类名,而是查找注释的结尾。但是,这不适用于多行的 cmets。类名是第三个捕获组。因此,要替换类名,只需触摸包含捕获组 3 的匹配项。

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

编辑:

我现在把它移植到 JS:

/(?=\/\*)|(\.[a-z][a-z0-9-_]*)(?!.*\*\/)/g

我仍然需要找到一种方法让它与多行一起工作。

【讨论】:

    【解决方案3】:

    试试这个正则表达式:

    \.[^{\s]*(?=\s*{)
    

    并用.a替换每个匹配项

    Click for Demo

    说明:

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

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

    /*# sourceMappingURL=style.css.map {*/
    

    即,{ 在评论中出现在 css.map 之后。因此,要处理这种情况,您可以使用以下正则表达式(几乎与上一个正则表达式相似。只是对正则表达式的负前瞻)

    \.[^{\s]*(?=\s*{)(?!(?:(?!\/\*)[\s\S])*\*\/)
    

    Click for Demo

    说明:

    • \.[^{\s]*(?=\s*{) - 类似于之前的正则表达式
    • (?!(?:(?!\/\*)[\s\S])*\*\/) - 负前瞻以确保当前位置(.classname 之后的位置)不存在于/*...*/ 形式的注释中
      • (?!.... - 负前瞻
      • (?:(?!\/\*)[\s\S])* - tempered greedy token 贪婪匹配 0+ 次出现的任何字符,它不以序列 /* 开头
      • \*\/ - 匹配 */

    【讨论】:

    • 这不适用于具有多个类的选择器。我错过了在我的问题中说明这一点。
    【解决方案4】:

    这两种方法都适用于不同的情况,例如 id 之间的类或选择中的多个类:

    .class-a, #id-a, .class-b:hover {}
    

    第一种方法

    在第一种方法中,您可以同时匹配注释部分和 CSS 类,然后在匹配时替换类名并保持 cmets 不变:

    \/\*[\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 ...
        }
    ));

    第二种方法

    如果您认为在 cmets 中不会存在这样的情况:

    /* style.css {css file} */
    

    您可以在第一种方法中省略匹配的 cmets:

    \.[a-z_-][\w-]*(?=[^{}]*{[^{}]*})
                             ^^^^^^^ 
                 Added for a more strict selection
    

    RegEx live demo

    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'));

    【讨论】:

      猜你喜欢
      • 2014-01-27
      • 1970-01-01
      • 2012-05-20
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 2020-02-07
      相关资源
      最近更新 更多