我正在从磁盘读取CSS文件作为字符串。
我的目标是提取与特定数据属性配对的HTML类:
.foo[data-my-attr]
data属性足够独特,所以我不必费心去遍历CSS AST。我可以简单地使用这样的正则表达式:
(\.\S+)+\[data-my-attr\]
这已经有效,但\S+
显然是一种匹配选择器中的HTML类的错误方法。它将包括各种组合器,伪类,伪选择器等。
我尝试构建正则表达式的白名单版本,e。 G。 (\w|-)+
,但类名的HTML5规范非常宽松。我不可避免地会错过某些字符或包含不正确的字符。
可以使用什么正则表达式从CSS选择器字符串中提取HTML5类?
我正在使用Node,i。即正则表达式的JavaScript风格。
一些例子:
.foo[data-my-attr]
- 应与.foo
.foo>span[data-my-attr]
- 不应该匹配.I_f%⌘ing_♥_HTML5[data-my-attr]
- 应与.I_f%⌘ing_♥_HTML5
这个问题的存在是因为我无法想到每一个可能有效的HTML5类。我需要一个基于令人惊讶的模糊HTML5类规范的正则表达式:
如果指定了属性,则该属性的值必须是一组以空格分隔的标记,表示该元素所属的各种类。
HTML元素分配给它的类包含在类空间上拆分class属性的值时返回的所有类。 (忽略重复。)
作者可以在class属性中使用令牌没有其他限制,但鼓励作者使用描述内容性质的值,而不是描述内容所需表示的值。
显然,一个类不应该包含+>:()[]=~
之类的空格和字符,因为它们是CSS选择器语法的一部分......
答案 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)