简体   繁体   English

Javascript有效解析css选择器

[英]Javascript efficient parsing of css selector

What would be the most efficient way of parsing a css selector input string, that features any combination of: 解析css选择器输入字符串的最有效方法是什么,它具有以下任意组合:

  • [key=value] : attributes, 0 to * instances [key=value] :属性,0到*实例
  • #id : ids, 0 to 1 instances #id :ids,0到1个实例
  • .class : classes, 0 to * instances .class :classes,0到*实例
  • tagName : tag names, 0 to 1 instances (found at start of string only) tagName :标记名称,0到1个实例(仅在字符串的开头找到)

(note: ' * ', or other applicable combinator could be used in lieu of tag?) (注意:' * '或其他适用的组合器可用于代替标签?)

Such as: 如:

div.someClass#id[key=value][key2=value2].anotherClass

Into the following output: 进入以下输出:

[' div ',' .someClass ',' #id ',' [key=value] ',' [key2=value2] ',' .anotherClass '] [' div ','。 .someClass ',' #id ',' [key=value] ',' [key2=value2] ','。 .anotherClass ']

Or for bonus points, into this form efficiently (read: a way not just based on using str[0] === '#' for example): 或者对于奖励积分,有效地进入这种形式(阅读:不仅仅基于使用str[0] === '#'的方式):

{
 tags : ['div'],
 classes : ['someClass','anotherClass'],
 ids : ['id'],
 attrs : 
   {
     key : value,
     key2 : value2
   }
}

(note removal of # . [ = ] ) (注意删除# . [ = ]

I imagine some combination of regex and .match(..) is the way to go, but my regex knowledge is nowhere near advanced enough for this situation. 我想象正则表达式和.match(..)一些组合是.match(..)的方法,但我的正则表达式知识远远不够先进。

Many thanks for your help. 非常感谢您的帮助。

You might do the splitting using 您可以使用分割

var tokens = subselector.split(/(?=\.)|(?=#)|(?=\[)/)

which changes 哪个改变了

div.someClass#id[key=value][key2=value2].anotherClass

to

["div", ".someClass", "#id", "[key=value]", "[key2=value2]", ".anotherClass"]

and after that you simply have to look how starts each token (and, in case of tokens starting with [ , checking if they contain a = ). 之后你只需看看每个令牌是如何启动的(并且,如果令牌以[ ,检查它们是否包含= )开头)。

Here's the whole working code building exactly the object you describe : 这是构建您描述的对象的整个工作代码:

function parse(subselector) {
  var obj = {tags:[], classes:[], ids:[], attrs:[]};
  subselector.split(/(?=\.)|(?=#)|(?=\[)/).forEach(function(token){
    switch (token[0]) {
      case '#':
         obj.ids.push(token.slice(1));
        break;
      case '.':
         obj.classes.push(token.slice(1));
        break;
      case '[':
         obj.attrs.push(token.slice(1,-1).split('='));
        break;
      default :
         obj.tags.push(token);
        break;
    }
  });
  return obj;
}

demonstration 示范

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM