Why is my regex not working as expected?

Asked

Viewed 49 times

2

I really have difficulty assembling regular expressions, mainly by varying their behavior in each language. I am translating a Java code for JS, in which the regular expression is /(\d{1,4}|\*)\s*[xX]\s*(\d{1,4}|\*)/, by what I understand it captures any number (size 1 to 4 characters) that has at least X or x separating from another set of numbers.
My question is: Why can’t I capture "1024x768 px up to 1920x1080" to give match also in "1920x1080"?

JS

function process(val) {
    if (val != null) {
        val = val.replace("X", "x");
        val = val.replace(/ /g, "");
        const DIMENSAO_UNIT = "px";
        const DIMENSAO_PATTERN = /(\d{1,4}|\*)\s*[xX]\s*(\d{1,4}|\*)/;
        var normalizado = val.trim().toLowerCase().replace(DIMENSAO_UNIT, "");
        var valores = [];
        var out = "";
        if (DIMENSAO_PATTERN.test(val)) {
            var getNumbers = val.match(DIMENSAO_PATTERN);
            var i = 0;
            for (i = 0; i < getNumbers.length; i++) {
                valores.push(getNumbers[i]);
            }
        }
        if(val == ""){
            return "";
        }
        if (normalizado.indexOf("superior") > -1) {
            return valores[0] + DIMENSAO_UNIT + " ou superior";
        } else if (normalizado.indexOf("até") > -1) {
            if (valores.length == 1) {
                out = "até " + valores[0];
            } else {
                out = valores[0] + " até " + valores[1];
            }
        } else if (normalizado.indexOf("ou") > -1 || normalizado.indexOf("/") > -1) {
            out = valores[0];
            var j = 0;
            for (j = 1; j < valores.length; j++) {
                out = "/" + valores[j];
            }
        } else {
            if (valores.length > 0) {
                out = valores[0];
            }
        }
        if (out !== null || out !== "") {
            return out + DIMENSAO_UNIT;
        }
        return "";
    }
    return null;
}


Regex test

**UPDATE: Only the global (g): /(\d{1,4}|\*)\s*[xX]\s*(\d{1,4}|\*)/g but I leave open for explanations

1 answer

2


The problem is not in regex, as you well noticed, but in the functions of Javascript handling regexes. The function match of the kind String returns:

  • The first marriage found, along with their capture groups, if the regular expression does not possess the flag g;
  • All marriages found if the regex posui the flag g. In this case, catch groups are ignored.

Example:

var str = "abracadabra";

var regex1 = /a(.)/;
var regex2 = /a(.)/g;

var match1 = str.match(regex1);
var match2 = str.match(regex2);

document.body.innerHTML += "<p>" + JSON.stringify(match1) + "</p>";
document.body.innerHTML += "<p>" + JSON.stringify(match2) + "</p>";

  • Only one question in the code: compiling online allows you to run this line in one: val = val.replace("X", "x").replace(/ /g, ""); but in intelliJ the second replace is not found as a function, I have to put as: val = val.replace("X", "x");val = val.replace(/ /g, "");. Is "freshness" of IDE or is this not allowed at all?

  • 1

    Javascript has dynamic typing, which makes it difficult to analyze a code statically and determine what a variable contains, what its type, what methods apply to it. We know the method replace returns a string - and therefore you can call string methods in return - but the IDE’s code parser won’t necessarily know this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.