正则表达式从CSS选择器字符串

时间:2017-11-25 11:41:55

标签: javascript css node.js regex html5

我正在从磁盘读取CSS文件作为字符串。

我的目标是提取与特定数据属性配对的HTML类:

.foo[data-my-attr] 

data属性足够独特,所以我不必费心去遍历CSS AST。我可以简单地使用这样的正则表达式:

(\.\S+)+\[data-my-attr\]

这已经有效,但\S+显然是一种匹配选择器中的HTML类的错误方法。它将包括各种组合器,伪类,伪选择器等。

我尝试构建正则表达式的白名单版本,e。 G。 (\w|-)+,但类名的HTML5规范非常宽松。我不可避免地会错过某些字符或包含不正确的字符。

可以使用什么正则表达式从CSS选择器字符串中提取HTML5类

我正在使用Node,i。即正则表达式的JavaScript风格。

UPD1

一些例子:

  • .foo[data-my-attr] - 应与.foo
  • 相匹配
  • .foo>span[data-my-attr] - 不应该匹配
  • .I_f%⌘ing_♥_HTML5[data-my-attr] - 应与.I_f%⌘ing_♥_HTML5
  • 相匹配

这个问题的存在是因为我无法想到每一个可能有效的HTML5类。我需要一个基于令人惊讶的模糊HTML5类规范的正则表达式:

  

3.2.5.7 The class attribute

     

如果指定了属性,则该属性的值必须是一组以空格分隔的标记,表示该元素所属的各种类。

     

HTML元素分配给它的类包含在类空间上拆分class属性的值时返回的所有类。 (忽略重复。)

     

作者可以在class属性中使用令牌没有其他限制,但鼓励作者使用描述内容性质的值,而不是描述内容所需表示的值。

显然,一个类不应该包含+>:()[]=~之类的空格和字符,因为它们是CSS选择器语法的一部分......

2 个答案:

答案 0 :(得分:2)

你不应该使用正则表达式。

更稳固的替代方案是PostCSS(及其解析器)。 有了它,您将获得整个样式表的完整AST(抽象语法树),通过它,您将能够轻松地提取您正在寻找的部分。

const postcss = require('postcss');
const Tokenizer = require('css-selector-tokenizer');

let output = [];

const postcssAttributes = postcss.plugin('postcss-attributes', function() {
  return function(css) {
    css.walkRules(function(rule) {
      rule.selectors.map(selector => {
        const tokenized = Tokenizer.parse(selector);
        if (
          tokenized.nodes.some(({ nodes }) =>
            nodes.some(
              node =>
                node.type === 'attribute' && node.content === 'data-my-attr'
            )
          )
        ) {
          output.push(selector);
        }
      });
    });
  };
});

const css = `
    .foo[data-my-attr] {
        color: red;
    }
    .foo[something] {
        color: red;
    }
`;

postcss([postcssAttributes])
  .process(css)
  .then(result => console.log(output));

// logs: [ '.foo[data-my-attr]' ]

这将记录所有匹配的选择器。

答案 1 :(得分:0)

匹配选择器字符串中的HTML5类的正则表达式为:

/\.-?(?:[_a-z]|[\240-\377]|(?:(:?\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?)|\\[^\r\n\f0-9a-f]))(?:[_a-z0-9-]|[\240-\377]|(?:(:?\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?)|\\[^\r\n\f0-9a-f]))*/

信用:@KOBA789

指向Alohci以指向正确的方向。