简体   繁体   中英

Javascript regular expression matching css selectors

I'm trying to match a regular expression against a set of css rules. This is the part of the code that is not working:

selector = $.trim(selector.replace('.', '\.'));
var re = new RegExp('/'+selector+'(?=\{| \{|   \{)/', 'g');

Here I'm escaping the fullstop in the selector in case it is a class eg ".styler".

Then I'm trying to match the specific selector which is followed by a curly bracket or one space and a curly bracket, or two spaces and a curly bracket.

What I'm trying to achieve is
Selector ".styler" matches: ".styler{" , ".styler {", ".styler {"
and do not match: ".styler span{", ".styler h1 {" etc.

Backslash escapes the next character also in JS string. You need to escape the backslash too:

selector = $.trim(selector.replace('.', '\\.'));

You could also simplify and generalize your regexp as follows:

selector = $.trim(selector.replace('.', ''));
var re = new RegExp('/[.#]*'+selector+'(?=\s*{)/', 'g');

It avoids the need for escaping and generalizes to any number of spaces (or tabs) between the selector and the left brace.

Ok so I finally found it based on the two answers. Had to keep the escaping Teemu suggested and removed the dots in case the changed rule is of the type ".div .h1". The new RegExp object didn't like the slashes into the pattern.

var regExpSelector = $.trim(selector.replace('.', '\\.')); 
var re = new RegExp(regExpSelector+"(?=\s*{)"); 

Here is the complete function if anyone is interested. Is is based mostly on splits and not regexes and it's not thoroughly tested. It also requires JQuery.

function updateCss(css, selector, styles){  
    var regExpSelector = $.trim(selector.replace('.', '\\.'));  
    var re = new RegExp(regExpSelector+"(?=\s*{)", "g"); 
    var temp1 = css.split(re);

    if (temp1.length>1){ //selector exists, update it               
        var oldCssBefore="";

        if (temp1.length>2){ //there is more than one entry for this selector, so we update the last one
            //rebuilding the stylesheet above the changed values
            for (i=0;i<temp1.length-1;i++){
                if ($.trim(temp1[i]).charAt(0)=="{") oldCssBefore += selector+" "+temp1[i];
                else oldCssBefore += temp1[i];
            }
            oldCssBefore += "\n"+selector+" {\n";                   
            var temp2 = temp1[temp1.length-1].replace("{","").split("}");               
        } else {
            //rebuilding the stylesheet above the changed values
            oldCssBefore = temp1[0]+"\n"+selector+" {\n";       
            temp1[1] = temp1[1].replace("{","");        
            var temp2 = temp1[1].split("}");        
        }   

        //capturing the desired css rules
        var newCss = temp2[0];      

        //rebuilding the stylesheet below the changed values
        var oldCssAfter="}\n";              
        for (i=1;i<temp2.length;i++) {
            if (temp2[i]!="" && typeof temp2[i]!="undefined" && temp2[i]!="\n" && temp2[i]!="\t") oldCssAfter += temp2[i]+"}";
        }               

        //adding the rules
        $.each( styles, function( key, value ) {            
            if (newCss.indexOf(key) > -1) { //rule exists, replace it
                var temp3 = newCss.split(key);          
                var newCssBefore = $.trim(temp3[0]);                

                temp3[1] = temp3[1].replace(":","");                
                var temp4 = temp3[1].split(";");

                var newCssAfter="";                     
                for (i=1;i<temp4.length;i++) {
                    console.log(temp4[i]);
                    temp4[i] = $.trim(temp4[i]);
                    if (temp4[i]!="" && typeof temp4[i]!="undefined" && temp4[i]!="\n" && temp4[i]!="\t") newCssAfter += temp4[i]+";\n";
                }               

                newCss = newCssBefore+" \n"+key+": "+value+"; \n"+newCssAfter;                              
            } else { //rule doesn't exist, add it               
                newCss += "\t"+key+": "+value+";\n";
            }
        }); 
        return oldCssBefore+"\n"+newCss+"\n"+oldCssAfter;           
    } else { //selector does not exist, add it
        var newCss = "";
        $.each( styles, function( key, value ) {
            //console.log(key);
            newCss += "\t"+key+": "+value+";\n";
        });

        css += selector+" {\n"+newCss+"\n}";
        return css;
    }   
}

USAGE:

var styles={'font-size':'18px', 'top':'10px', 'left':'20px'};
var css = updateCss(styleSheetStringHere, ".div", styles);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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