1

I'm trying to get some filter properties of a DOM element, such as opacity, blur, etc. At the moment I'm splitting the string and then trying to match the string tokens against known filter types using regex. My question:

I'm having trouble with the logical OR in the regex below - I'm trying to match "opacity(0.234) or opacity(1)" for example.

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
  1. What have I screwed up? (It's returning false on most tests where it should be true)

  2. Is there a better way (i.e. a way to access the various constituent parts of the filter string with object notation or something similar)? Parsing strings to fish out properties is painful.

0

2 Answers 2

1

You forgot to double \ everywhere. Also, there is no point of overusing capturing groups, I suggest removing them and replacing with non-capturing ones so as not to cluster the match object.

Here are the changes I suggest:

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer! Do you recommend extracting css filter values this way though, or is there a better, more appropriate way to do it?
I am no expert in css filters, but if it is plain text and there are no nested constructions, you can use regex to extract whatever you need.
I decided to accept this answer because it seems no-one else has a suggestion of a way to access the various filter parameters directly.
1

For reference of anyone else hoping to do the same thing, here's a code template. I'm still looking for a more elegant way of accessing the parameters' values directly because this is ugly.

//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(')','');
            }
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.