Why is my variable null?

Asked

Viewed 184 times

2

I am translating a function from Java to JS, the logic remains the same but the results are different.
In the regular expression test, returns match when I test 40kb but when compiling the code I get a null on an unspecified line.

Why when testo "2kb" is not null and with "40kb" I get JS error?

Log

Error:
TypeError: getNumbers is null

JS

 function process(val) {
        var isPeso = "(?:k|m|g)b$";
        var normalizado = val.trim().toLowerCase().replace(" ", "");
        var unidade = "";
        var numberPattern = "\d+(\.\d{1,2})?|(Livre)/i";

        var myArray = normalizado.match(isPeso);
        if (myArray != null) {
            unidade = myArray;

            var getNumbers = val.match(numberPattern);
            var i;
            var valores = [];
            for (i = 0; i < getNumbers.length - 1; i++) {
                valores.push((getNumbers[i]))
            }

            var out = "";
            //Caso [X ou superior]
            if (normalizado.indexOf("superior") > -1) {
                return valores[0] + unidade + " ou superior";
            }
            //Caso [X até Y] e [até Y]
            else if (normalizado.indexOf("até") > -1) {
                //Caso [até Y]
                if (valores.length == 1) {
                    out = "até " + valores[0];
                }
                //Caso [X até Y]
                else {
                    out = valores[0] + " até " + valores[1];
                }
            }

            //Caso [X ou Y] ou [X ou Y ou ...]
            else if (normalizado.indexOf("ou") > -1 || normalizado.indexOf("/") > -1) {
                out = valores[0];
                for (i = 1; i < valores.length -1; i++) {
                    out += valores[i];
                }
            }
            //Caso livre
            else if (normalizado.indexOf("*") > -1 || normalizado.indexOf("livre") > -1) {
                out = "Livre";
            }
            //Caso X
            else {
                if (valores.length > 0) {
                    out = valores[0];
                }
            }
            if (out.length == 0 || out == null) {
                return "";
            }
            return out + unidade;
        }
    }

Java

public class IntervaloHandler implements LanguageInterface{
    public static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+(\\.\\d{1,2})?|(Livre)", Pattern.CASE_INSENSITIVE);
     public String normalizar(String in) throws LanguageHandler.NormalizarExcception {
            //Trim e LowerCase
            String normalizado = in.trim().toLowerCase(new Locale("pt", "BR"));

            //Identifica a unidade
            String unidade = "";

            Pattern tempoPattern = Pattern.compile("s$");
            Matcher tempoMatcher = tempoPattern.matcher(normalizado);

            Pattern bytesPattern = Pattern.compile("(k|m|g)b$");
            Matcher matcher = bytesPattern.matcher(normalizado);

            //Bytes (PESO)
            if(matcher.find()){
                unidade = matcher.group();
            }

            //Encontra os valores e formata
            ArrayList<String> valores = new ArrayList<>();
            Matcher m = NUMBER_PATTERN.matcher(in);
            while(m.find()){
                valores.add(m.group().replaceAll(" ", ""));
            }
            String out = "";





            //Caso [X ou superior]
            if(normalizado.contains("superior")){
                return String.format("%s%s ou superior", valores.get(0), unidade);
            }
            //Caso [X até Y] e [até Y]
            else if(normalizado.contains("até")){
                //Caso [até Y]
                if(valores.size() == 1){
                    out = String.format("até %s", valores.get(0));
                }
                //Caso [X até Y]
                else{
                    out = String.format("%s até %s", valores.get(0), valores.get(1));
                }
            }
            //Caso [X ou Y] ou [X ou Y ou ...]
            else if(normalizado.contains("ou") || normalizado.contains("/")){
                out = valores.get(0);
                for(int i=1; i < valores.size(); i++){
                    out += String.format("/%s", valores.get(i));
                }
            }
            //Caso livre
            else if(normalizado.contains("*") || normalizado.contains("livre")) {
                out = "Livre";
            }
            //Caso X
            else {
                if(valores.size() > 0)
                    out = valores.get(0);
            }




            //Coloca a unidade no final
            return out.isEmpty() ? "" : String.format("%s%s", out, unidade);
        }
}
  • Tried to use /\d+(\.\d{1,2})?|(Livre)/i for regular expression and replace var getNumbers = numberPattern.match(val); for var getNumbers = val.match(numberPattern);?

  • The error remains the same.

  • 1

    You’re using the regular expression as literal, like this: var numberPattern = /\d+(\.\d{1,2})?|(Livre)/i;? Or as a string?

  • I was using as String, as literal I didn’t get the error anymore! I didn’t get the expected result but obg.

  • What is the expected result? Update your question that I may be able to help you, hence an answer.

  • These are just some examples of cases, probably not entering the loop of the respective Return’s, I will test 1) input = "20 Mb", expected = "20mb"; 2) input = "20 Mb or 10mb", expected = "20/10mb"; 3) input = "up to 10Mb", expected = "up to 10mb";

  • Yeah, in this case you’d have to check her entire function, she’s got some problems, even logic. You can solve everything with regular expressions, such as using clusters and picking up the parts you want. In this case, test and if you do not realize post your doubts :)

Show 2 more comments

1 answer

2


Its variable is null because the regular expression does not "house" anything in the examples, not even 2kb worked around here.

It does not match any part of the input because it is not a valid regular expression of the way it is declared, i.e., the syntax is incorrect.

Prefer to use regular expressions literal. So instead of this:

"\d+(\.\d{1,2})?|(Livre)/i"

use this:

/\d+(\.\d{1,2})?|(Livre)/i

But why? Well, this \ is a string escape character, so prefer literals to be more elegant and even more readable and simple to represent the expression, otherwise you would need this:

"\\d+(\\.\\d{1,2})?|(Livre)\/i"

or this:

var reg = new RegExp("\\d+(\\.\\d{1,2})?|(Livre)", "i");

Much more convenient to use literals, it’s not? =)

See an example of the literal form:

function process(val) {
    var isPeso = "(?:k|m|g)b$";
    var normalizado = val.trim().toLowerCase().replace(" ", "");
    var unidade = "";
    var numberPattern = /\d+(\.\d{1,2})?|(Livre)/i;

    var myArray = normalizado.match(isPeso);
    if (myArray != null) {
        unidade = myArray;

        var getNumbers = val.match(numberPattern);
        var i;
        var valores = [];
        for (i = 0; i < getNumbers.length - 1; i++) {
            valores.push(getNumbers[i]);
        }

        var out = "";
        //Caso [X ou superior]
        if (normalizado.indexOf("superior") > -1) {
            return valores[0] + unidade + " ou superior";
        }
        //Caso [X até Y] e [até Y]
        else if (normalizado.indexOf("até") > -1) {
            //Caso [até Y]
            if (valores.length == 1) {
                out = "até " + valores[0];
            }
            //Caso [X até Y]
            else {
                out = valores[0] + " até " + valores[1];
            }
        }

        //Caso [X ou Y] ou [X ou Y ou ...]
        else if (normalizado.indexOf("ou") > -1 || normalizado.indexOf("/") > -1) {
            out = valores[0];
            for (i = 1; i < valores.length - 1; i++) {
                out += valores[i];
            }
        }
        //Caso livre
        else if (normalizado.indexOf("*") > -1 || normalizado.indexOf("livre") > -1) {
            out = "Livre";
        }
        //Caso X
        else {
            if (valores.length > 0) {
                out = valores[0];
            }
        }
        if (out.length == 0 || out == null) {
            return "";
        }
        
        return out + unidade;
    }
}
function test() {
    var val = document.getElementById("input").value;
    var result = process(val);
    document.getElementById("span").innerHTML = "Resultado: entrada: " + val + " | saida: " + result;
}
<input id="input" />
<button onclick="test()">GO</button>
<p>
    <span id="span">Resultado: </span>
</p>

And one using string "escapes":

function process(val) {
    var isPeso = "(?:k|m|g)b$";
    var normalizado = val.trim().toLowerCase().replace(" ", "");
    var unidade = "";
    var numberPattern = "\\d+(\\.\\d{1,2})?|(Livre)\/i";

    var myArray = normalizado.match(isPeso);
    if (myArray != null) {
        unidade = myArray;

        var getNumbers = val.match(numberPattern);
        var i;
        var valores = [];
        for (i = 0; i < getNumbers.length - 1; i++) {
            valores.push(getNumbers[i]);
        }

        var out = "";
        //Caso [X ou superior]
        if (normalizado.indexOf("superior") > -1) {
            return valores[0] + unidade + " ou superior";
        }
        //Caso [X até Y] e [até Y]
        else if (normalizado.indexOf("até") > -1) {
            //Caso [até Y]
            if (valores.length == 1) {
                out = "até " + valores[0];
            }
            //Caso [X até Y]
            else {
                out = valores[0] + " até " + valores[1];
            }
        }

        //Caso [X ou Y] ou [X ou Y ou ...]
        else if (normalizado.indexOf("ou") > -1 || normalizado.indexOf("/") > -1) {
            out = valores[0];
            for (i = 1; i < valores.length - 1; i++) {
                out += valores[i];
            }
        }
        //Caso livre
        else if (normalizado.indexOf("*") > -1 || normalizado.indexOf("livre") > -1) {
            out = "Livre";
        }
        //Caso X
        else {
            if (valores.length > 0) {
                out = valores[0];
            }
        }
        if (out.length == 0 || out == null) {
            return "";
        }
        
        return out + unidade;
    }
}
function test() {
    var val = document.getElementById("input").value;
    var result = process(val);
    document.getElementById("span").innerHTML = "Resultado: entrada: " + val + " | saida: " + result;
}
<input id="input" />
<button onclick="test()">GO</button>
<p>
    <span id="span">Resultado: </span>
</p>

  • Perfect, thank you. For unknown reasons, Nashorn is not running this script (javax.script.ScriptException: TypeError: Cannot get property "length" of null in <eval> at line number 1).

  • @Danielamarquesdemorais good, using the first example, treating the function to be evaluated by nashorn, worked OK. Input aa20kb, exit 20kb. Which entrance did you test?

  • "50kb" and get the ScriptException

  • @Danielamarquesdemorais see if this gist help you.

Browser other questions tagged

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