正则expression式从CSSselect器string中提取HTML5类

我正在从磁盘读取CSS文件作为string。

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

.foo[data-my-attr] 

数据属性是独一无二的,所以我不必担心遍历CSS AST。 我可以简单地使用这样的正则expression式:

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

这已经可以工作了,但是\S+在select器中匹配一个HTML类是一个不错的方法。 它将包括各种组合器,伪类,假select器等。

我尝试构build正则expression式的白名单版本,例如(\w|-)+ ,但类名称的HTML5规范是非常宽容的。 不可避免的是,我错过了某些字符或者包含不正确的字符。

什么正则expression式可以用来从CSSselect器string中提取HTML5类

我正在使用Node,即正则expression式的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类规范的正则expression式:

3.2.5.7类属性

该属性(如果指定)必须具有一个值,该值是一组空格分隔的标记,表示该元素所属的各个类。

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

对于作者可以在类属性中使用的标记没有额外的限制,但鼓励作者使用描述内容本质的值,而不是描述所需内容表示的值。

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

你不应该使用正则expression式。

PostCSS(和它的parsing器)是一个更稳定的select。 有了它,你将得到整个样式表的完整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]' ] 

这将logging所有匹配的select器。

匹配select器string中的HTML5类的正则expression式是:

 /\.-?(?:[_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 Thx指向正确的方向。