我正在尝试获取DOM元素的一些过滤器属性,如不透明度、模糊等。目前我正在拆分字符串,然后尝试使用regex将字符串标记与已知的过滤器类型进行匹配。我的问题:
我在下面的正则表达式中遇到了逻辑OR的问题——例如,我试图匹配"opacity(0.234)或opacity)(1)"。
var re1="(opacity)"; // word "opacity"
var re2="(\()"; // single character '('
var re3 = "(0(.d+)?)" //0, with possible decimals after
var re4 = "(1)" //single character '1'
var re3or4 = "("+re3+"|"+re4+")"; //logical or
var re5 = "(\))"; //single character ')'
var reg = new RegExp(re1+re2+re3or4+re5, "i");
//unit tests
console.log(reg.test("opacity(0)")); //true
console.log(reg.test("opacity(0.4)")); //true
console.log(reg.test("opacity(1)")); //true
console.log(reg.test("opacity()")); //false
console.log(reg.test("opacity")); //false
我搞砸了什么?(在大多数测试中,它都返回false,而应该是true)
是否有更好的方法(即使用对象表示法或类似方法访问过滤器字符串的各个组成部分)?解析字符串以获取属性是痛苦的。
您忘记在任何地方都加倍。此外,没有必要过度使用捕获组,我建议删除它们并用非捕获组替换,以免对匹配对象进行聚类。
以下是我建议的更改:
var re1="opacity"; // word "opacity"
var re2="\("; // single character '('
var re3 = "0(?:\.\d+)?" //0, with possible decimals after
// ^^ ^^
var re4 = "1" //single character '1'
var re3or4 = "("+re3+"|"+re4+")"; //logical or
var re5 = "\)"; //single character ')'
var reg = new RegExp(re1+re2+re3or4+re5, "i"); // => /opacity((0(?:.d+)?|1))/i
var re1="opacity"; // word "opacity"
var re2="\("; // single character '('
var re3 = "0(?:\.\d+)?" //0, with possible decimals after
var re4 = "1" //single character '1'
var re3or4 = "("+re3+"|"+re4+")"; //logical or
var re5 = "\)"; //single character ')'
var reg = new RegExp(re1+re2+re3or4+re5, "i"); // => /opacity((0(?:.d+)?|1))/i
console.log(reg);
//unit tests
console.log(reg.test("opacity(0)")); //true
console.log(reg.test("opacity(0.4)")); //true
console.log(reg.test("opacity(1)")); //true
console.log(reg.test("opacity()")); //false
console.log(reg.test("opacity")); //false
为了参考其他希望做同样事情的人,这里有一个代码模板。我仍然在寻找一种更优雅的方式来直接访问参数的值,因为这很难看。
//example properties with default values
var properties = {
"sepia": 0,
"saturate": 1,
"opacity": 1
//add your own...
}
//set up the regex
var re2 = "\("; // single character '('
var re3 = ".*"; //match any character multiple times
var re5 = "\)"; //single character ')'
//parse the values
var el = document.getElementById("blah");
var filterStrings = el.style.filter.split(" "); //generate array of filter property strings
for(var p in properties){
if(properties.hasOwnProperty(p)){
//loop through all the filter strings and see if we have a match with current property p
for(var i = 0; i < filterStrings.length; i++){
//construct regular expression based on current property p
var reg = new RegExp(p+re2+re3+re5, "i");
if(reg.test(filterStrings[i])){
//if we have a match, strip the filter name and save the value
properties[p] = filterStrings[i].replace(p,'').replace('(','').replace(')','');
}
}
}
}