我已创建此代码来计算css规则优先级
var selectorText = "body";
A = selectorText.match(/#/gm); // id
A = !A ? 0 : A.length;
B1 = selectorText.match(/\\./gm); // class
B1 = !B1 ? 0 : B1.length;
B2 = selectorText.match(/[[]/gm); // attribute selector
B2 = !B2 ? 0 : B2.length;
B3 = selectorText.match(/[\\w\\d_\\s^]:(?!:)/gm); // pseudo třída
B3 = !B3 ? 0 : B3.length;
B = B1 + B2 + B3;
C1 = selectorText.match(/::/gm); // pseudo element
C1 = !C1 ? 0 : C1.length;
C2 = selectorText.match(/\\w+[$\\s#\\.:\\[]/gm); // element
C2 = !C2 ? 0 : C2.length;
C = C1 + C2;
A *= 10000;
B *= 100;
alert(C)
选择器中的匹配项不得超过100个(A,B或C)。 由于某种原因,C的结果是0(但我使用“body”选择器)。你能建议如何纠正最后一场比赛吗?你也看到代码中有任何错误吗?
注意:
原始问题只是“body”选择器,但我想到任何选择器或多个这样的选择器:“div#menu ul li,div#id,div.class”选择器可以包含伪类,伪元素,属性选择器。在C2正则表达式的情况下,我试图找到在最后一个字符串中总共有5个元素的元素数(然后C2应该是5)。
答案 0 :(得分:2)
selectorText
不包含::
,C1 = selectorText.match(/::/gm);
应该返回null
; C1 = !C1 ? 0 : C1.length;
返回0
; C2 = selectorText.match(/\\w+[$\s#\\.:\\[]/gm);
返回null
,C2 = !C2 ? 0 : C2.length;
返回0
; C = C1 + C2;
等于0
;那是0 + 0 = 0
原始问题只是“身体”选择器,但我想到了 任何选择器或多个选择器如下:“div#menu ul li,div#id, div.class“选择器可以包含伪类,伪元素, 属性选择器。在C2正则表达式的情况下,我试图找到 最后一个字符串中的元素总数为5个元素 (那么C2应该是5)
您可以.split()
与RegExp
/,|\s/
一起使用,
字符分割多个选择器; .map()
,.filter(Boolean)
删除空字符串.match()
,RegExp
/^[a-z]+(?=[.#:\s]|$)/i
以匹配元素。
var selectorText = "div#menu ul li, div#id, div.class";
C2 = selectorText.split(/,|\s/).filter(Boolean)
.map(el => el.trim().match(/^[a-z]+(?=[.#:\s]|$)/i)[0]);
console.log(C2);
答案 1 :(得分:0)
首先,我需要解决如何解析多个选择器的问题。正如Oriol所说,我不能用正则表达式解析多个选择器。这个功能可以满足我的需要。
String.prototype.findStrings = function (s = ',') {
var prev = null, prevEscaped = null, typq = null,
typp = null, depRB = 0, depSB = 0;
var obj = { length: 0,
results: { array: [], A: null, B: null, C: null }
};
var action = null;
if (s.constructor === Array)
{
action = 1;
}
else
{
if (typeof s === 'string' || s instanceof String)
action = 0;
}
if ( action === null)
return false;
for (var i=0; i<this.length; i++)
{
// not escaped:
if (!prevEscaped)
{ // not escaped:
switch (this[i])
{
case '\\':
prevEscaped = true;
prev = '\\'; // previous escaped
break;
case '"':
if (!typq)
{
typq = '"';
}
else if ( typq=='"' )
{ // end quotes
typq = null;
continue;
}
break;
case "'":
if (!typq)
{
typq = "'";
}
else if ( typq=="'" )
{ // end quotes
typq = null;
continue;
}
break;
}
}
else
{ // is escaped - do nothing
prevEscaped = false;
prev = null;
continue;
}
if (!typq) // no quotes block
{
switch (this[i])
{
case '(':
if (!typp)
typp = '('; // defines higher priority of () parenthesis
depRB++;
break;
case "[":
if (!typp)
typp = '[';
depSB++;
break;
case ")":
depRB--;
if (!depRB)
{
if ( typp == "(" )
{
typp = null; // end block of parenthesis
continue;
}
}
break;
case "]":
depSB--;
if (!depSB)
{
if ( typp == "[" )
{
typp = null; // end block of parenthesis
continue;
}
}
break;
}
}
if (typp) // commas inside block of parenthesis of higher priority are skipped
continue;
if (!action) // Separate by string s
{
if ( this[i] == s )
{
obj.results.array.push(i);
obj.length++;
}
}
else
{
}
// Block of no quotes, no parenthesis follows
} // end for
// Last item
obj.results.array.push(i);
obj.length++;
return obj;
};
/* Return array of strings */
String.prototype.splitFromArray = function (arr, autotrim = true) {
var prev = 0, results = [];
for (var i = 0; i<arr.length; i++)
{
var s = "";
s = this.substring(prev+1,arr[i]).trim();
results.push( s );
prev = arr[i];
}
return results;
};
这是这样实现的:
var test = '#a > :matches(.b, #c) , input.match(title="\\City \\"of ' + "'" + 'silly' + "'" +' people.", data=' + "'alpha=" + '"' + "string" + '"' + ",beta=2'" + ' value="New York"), article.class1 ul li';
var separators = test.findStrings();
console.log(separators);
var myArr = test.splitFromArray(separators.results.array);
console.log(myArr);
很抱歉,选择器在示例中无效,但这只是说明解析。您可以对其进行编辑以获得有效的选择器。
添加搜索规则并不难。