正则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指向正确的方向。