[Resolvido] Validar fórmula matemática que está como String

59 respostas
R

Boa tarde galera, tudo certo ? Bem, na minha aplicação tenho um campo em que o professor digita uma fórmula. Esta, vai servir para que ele avalie seus alunos. Nessa fórmula, o professor só podera digitar as letras np e números de 1 a 9 . Também, vai ser necessário verificar os parênteses, etc…
Abaixo, exemplo de fórmula:

((np1*0.25)+(np2*0.25)+(np3*0.25)+(np4*0.25))

Por exemplo, se o professor digitasse (np1 + ns2)/2, deveria informar um erro na fórmula…Se alguém puder ajudar, agradeço mto…Vlww

59 Respostas

Rodrigo_Sasaki

Você quer algo que te diga se a expressão é válida ou não? É isso?

R

Boa tarde Rodrigo, tdo certo? Não, na vdd estou tentando fazer o seguinte: Deixar o professor somente digitar np… Por exemplo:

(np1 + np2 +n np3 + np4 )/4

Se ele tentar colocar:

(ns1 + ns2 +n np3 + np4 )/4

Viria uma mensagem na tela por exemplo: verifique a fórmula… Além disso, também quero fazer ( depois que eu conseguir isso) verificar tipo, parênteses e tal, pra ver se estão sendo utilizandos no lugar correto…Não sei se fui claro… Mas conseguiu entender o início?? Tipo, ele só vai poder digitar as LETRAS NP… tendeu?? Daí vou ter que fazer a verificação quando ele salva, dentro do meu bean:

public void salva() { if (crudObj.getRecuperacao().equals("N")) { crudObj.setNotaRecuperacao(null); } if (!crudObj.getFormulaAvaliacao().isEmpty()) { //aki viria a verificação... } super.salva();
Se puder ajudar, agradeço mto… Vlw

R

Estou pesquisando aki sobre o uso de expressões regulares…Não sei se é a melhor forma de fazer as verificações que preciso…Alguém poderia ajudar?? Se alguém puder ajudar, agradeço mto…Vlw

Rodrigo_Sasaki

Você pode usar uma expressão regular sim, o ideal é você definir o que pode aparecer na sua expressão. por exemplo:

1 - Números
2 - Parênteses
3 - Operadores matemáticos (+, -, *, /)
4 - np seguido de algum número

Qualquer coisa fora disso não seria válida. Então a regex teria que verificar todos os caracteres vendo se eles caem nesses critérios. Algo assim:private static boolean matches(String expr){ Pattern p = Pattern.compile("(\\d*|[+*/().-]|np\\d+|\\s+)*"); Matcher m = p.matcher(expr); return m.matches(); }

Ataxexe

Já que você terá sempre 4 notas, uma ideia simples é fazer um javascript com a fórmula no programa em java, atribuir a nota zero para as variáveis np1 a np4 e pegar o output da execução da fórmula. Você terá um belo erro se a fórmula estiver sintaticamente incorreta e é só tratar esse caso.

Um exemplo você pode ver no próprio tópico que você abriu semana passada na mensagem do mauricioadl:

http://www.guj.com.br/java/304513-resolvido-interpretar-formula-matematica-que-esta-como-string

R

Rodrigo Sasaki:
Você pode usar uma expressão regular sim, o ideal é você definir o que pode aparecer na sua expressão. por exemplo:

1 - Números
2 - Parênteses
3 - Operadores matemáticos (+, -, *, /)
4 - np seguido de algum número

Qualquer coisa fora disso não seria válida. Então a regex teria que verificar todos os caracteres vendo se eles caem nesses critérios. Algo assim:private static boolean matches(String expr){ Pattern p = Pattern.compile("(\\d*|[+*/().-]|np\\d+|\\s+)*"); Matcher m = p.matcher(expr); return m.matches(); }


Bom dia Rodrigo…Isso aí caa, excelente idéia…Os quatro itens que você citou posso utilizar sim!! Mas, como eu poderia fazer pra testar se foi digitado algo fora do contexto que o profesor pode digitar no caso, algo fora dos 4 itens?? Vlw por estar ajudando cara!!

R

Ricardo Fávero Júnior:
Rodrigo Sasaki:
Você pode usar uma expressão regular sim, o ideal é você definir o que pode aparecer na sua expressão. por exemplo:

1 - Números
2 - Parênteses
3 - Operadores matemáticos (+, -, *, /)
4 - np seguido de algum número

Qualquer coisa fora disso não seria válida. Então a regex teria que verificar todos os caracteres vendo se eles caem nesses critérios. Algo assim:private static boolean matches(String expr){ Pattern p = Pattern.compile("(\\d*|[+*/().-]|np\\d+|\\s+)*"); Matcher m = p.matcher(expr); return m.matches(); }


Bom dia Rodrigo…Isso aí caa, excelente idéia…Os quatro itens que você citou posso utilizar sim!! Mas, como eu poderia fazer pra testar se foi digitado algo fora do contexto que o profesor pode digitar no caso, algo fora dos 4 itens?? Vlw por estar ajudando cara!!

No caso, como vou testar quando vou salvar, devo fazer dessa maneira? :

private static boolean matches(String expr) {
        Pattern p = Pattern.compile("(\\d*|[+*/().-]|np\\d+|\\s+)*");
        Matcher m = p.matcher(expr);
        return m.matches();
    }

    @Override
    public void salva() {
        if (crudObj.getRecuperacao().equals("N")) {
            crudObj.setNotaRecuperacao(null);
        }
        if (!crudObj.getFormulaAvaliacao().isEmpty()) {
          matches(crudObj.getFormulaAvaliacao());
        }
        super.salva();
    }
Rodrigo_Sasaki

Não, o matches retorna um boolean, você tem que decidir o que fazer dependendo do valor que ele retornar.

R

Blz… Vou testar aki e já posto o resultado…Vlww

R

Fiz da seguinte maneira:

private boolean formulaAvaliacaoVerdadeira() {
        Pattern p = Pattern.compile("(\\d*|[+*/().-]|np\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulaAvaliacao());
        return m.matches();
    }

    @Override
    public void salva() {
        if (!crudObj.getFormulaAvaliacao().isEmpty()) {
            if (formulaAvaliacaoVerdadeira()) {
                if (crudObj.getRecuperacao().equals("N")) {
                    crudObj.setNotaRecuperacao(null);
                }
                super.salva();
            } else {
                JsfUtil.warn("Fórmula de Avaliação Inválida. Verifique.");
            }
        }
    }

Funcionou perfeitamente Rodrigo. Vc como sempre, vem com boas ideias quando responde os tópicos aki ehehe. Cara, mas estou afim de ir mais além… Teria como verificar mais " a fundo " a expressão ? No caso, por exemplo do seguinte:

((np1*0.25)+(np2*0.25)+(np3*0.25)+(np4*0.25)))

Se a expressão tiver um parênteses a mais… Dá pra dar uma ajuda aí?? Vlw…

Rodrigo_Sasaki

Bom, aí você vai ter que ser criativo :slight_smile:

Dizem que o custo de realizar o cálculo é o mesmo, ou pelo menos é muito próximo, do custo de validar a expressão. Então eu nem faria isso, tentaria avaliar a expressão, se alguma exceção fosse lançada eu repassaria.

mas se quiser fazer isso mesmo pode simplesmente contar os parênteses. Pegue uma variável numérica, para cada parênteses aberto incremente 1, para cada fechado decremente 1. No final essa variável tem que ter valor 0

R

Rodrigo Sasaki:
Bom, aí você vai ter que ser criativo :slight_smile:

Dizem que o custo de realizar o cálculo é o mesmo, ou pelo menos é muito próximo, do custo de validar a expressão. Então eu nem faria isso, tentaria avaliar a expressão, se alguma exceção fosse lançada eu repassaria.

mas se quiser fazer isso mesmo pode simplesmente contar os parênteses. Pegue uma variável numérica, para cada parênteses aberto incremente 1, para cada fechado decremente 1. No final essa variável tem que ter valor 0


Bhá cara, boa idéia…Estou vendo como vc fez e queria sabeer o seguinte: se eu tiver a seguinte fórmula:

(nt+ne)/2

Podendo também ser:

((nt*0.25)+ne*0.25))/2

Como ficaria a expressão? Ou melhor, como coloco que pode ter somente nt e ne e não pode ter números depois deles ( diferente da outra que tenho por exemplo np1, np2). To tentando ver naquela que me passou mas nao to conseguindo descobrir…

Rodrigo_Sasaki

Expressões regulares tem que ser pensadas passo a passo, vamos pegar o seu caso.

O primeiro caractere tem que ser um n, então nossa regex representa isso:

regex -> “n”

O segundo caractere pode ser t ou e

regex -> “n[te]”

E assim você vai evoluindo

R

Rodrigo Sasaki:
Expressões regulares tem que ser pensadas passo a passo, vamos pegar o seu caso.

O primeiro caractere tem que ser um n, então nossa regex representa isso:

regex -> “n”

O segundo caractere pode ser t ou e

regex -> “n[te]”

E assim você vai evoluindo


Hm, to entendendo…No meu caso então, ficaria quase assim?

private boolean formulaAvalMediaFinalVerdadeira() {
        Pattern p = Pattern.compile("(\\d*|[+*/().-]|n[te]\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulAvalMediaFinal());
        return m.matches();
    }

Uma dúvida: essa parte |n[te]\d+|\s+ diz repeito as variáveis que pode ter na expressão e que tem números, é isso ? Se não qeuro que tenha números, como ficaria?? To lendo aki oque encontrei: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html

Rodrigo_Sasaki

Se não quer que tenha números não pode ter o \d+ na frente :slight_smile:

R

Rodrigo, fiz o seguinte entao:

private boolean formulaAvalMediaFinalVerdadeira() {
        Pattern p = Pattern.compile("(\\d*|[+*/().-]|n[te]\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulAvalMediaFinal());
        return m.matches();
    }

Para a seguinte fórmula,por exemplo:

(nt + ne)/2

E tá retornando false, poderia dizer o pq??Vlw…

Rodrigo_Sasaki

Por que você disse que o nt ou ne precisam ter um número na frente.

n[te]\d+

R

Rodrigo Sasaki:
Por que você disse que o nt ou ne precisam ter um número na frente.

n[te]\d+


Desculpe cara, desculpe msms, depois que postei fui ver a mesangem denovo… Mal aí…

R

Rodrigo Sasaki:
Bom, aí você vai ter que ser criativo :slight_smile:

Dizem que o custo de realizar o cálculo é o mesmo, ou pelo menos é muito próximo, do custo de validar a expressão. Então eu nem faria isso, tentaria avaliar a expressão, se alguma exceção fosse lançada eu repassaria.

mas se quiser fazer isso mesmo pode simplesmente contar os parênteses. Pegue uma variável numérica, para cada parênteses aberto incremente 1, para cada fechado decremente 1. No final essa variável tem que ter valor 0


Certa vez, na faculdade, acredito que foi no 3º Semestre do Curso (estou no 4º semestre) de Ciência da Computação, fiz o seguinte em C++ para verificar os parênteses…

#include <iostream>
#include <stack>
 
using namespace std;
 
    int main (){
 
        int N;
        string caracter;
        while (cin >> caracter){
            stack <int> pilha1, pilha_2; // declaracao da pilha (no caso inteiros numeros)
            for(int i=0; i < caracter.size(); i++){
                if(caracter[i] =='('){
                    pilha1.push(caracter[i]); // caracter[i]eh o q eu quero por na pilha
                }
                if(caracter[i] == ')'){  // verifica o caracter & ve se a pilha não esta vazia
                    pilha_2.push(caracter[i]);
                }
                if(caracter[i] == ')' && pilha1.size() != 0){  //  pilha.size() != 0 eh pra ver se ta vasia
                    pilha1.pop();
                    pilha_2.pop();
                }
        }
        if(pilha1.size() == 0 && pilha_2.size() == 0){
            cout << "correct" << endl;
        }else{
            cout << "incorrect" << endl;
        }
        }
 
return 0;
}

Estou tentando agora fazer isso em java…Não estou tendo mto sucesso… Não sei se devo usar um Stack tbm…Alguma idéia?? Estou tentando fazer da seguinte maneira: Devo ler a string ( minha fórmula) e contar quantas vezes aparece o caracter “(” e depois tbm ler e contar quantas vezes aparece o “)” . Se forem iguais a zero quando diminuo os dois, está correto, caso contrário falso…

private boolean testeIncrementaDecrementa() {
        int incr = 0;
        int decr = 0;
        String caracter = "(";
        String caracter2 = ")";
        for (int i = 0; i < crudObj.getFormulaAvaliacao().length(); i++) {
            if (crudObj.getFormulaAvaliacao().contains(caracter)) {
                incr = incr + 1;
            }
            if (crudObj.getFormulaAvaliacao().contains(caracter2)) {
                decr = decr + 1;
            }
        }
        if (incr - decr != 0) {
            return false;
        } else {
            return true;
        }
    }

Poderia continuar ajudando?? Vlw cara, vlw mesmo por estar ajudando…

R

Consegui fazer da seguinte forma:

public boolean verificaQuantParentesesFormulAnual() {
        int n = -1;
        int n2 = -1;
        int nroVezesabre = 0;
        int nroVezesfecha = 0;
        String formula = crudObj.getFormulaAvaliacao().toLowerCase();
        for (;; ++nroVezesabre) {
            n = formula.indexOf("(", n + 1);
            if (n == -1) {
                break;
            }
        }
        for (;; ++nroVezesfecha) {
            n2 = formula.indexOf(")", n2 + 1);
            if (n2 == -1) {
                break;
            }
        }
        if (nroVezesabre - nroVezesfecha != 0) {
            return false;
        } else {
            return true;
        }
    }

Só que daí ele só conta, e não empilha e desempilha os parênteses…Poderia dar uma ajuda para implementarmos isso? Ou é vantagem alterar a que mandei anteriormente?? Vlww

Rodrigo_Sasaki

Pra que você quer empilhar os parênteses?

Ataxexe

Ricardo, por quê você não deu uma olhada no que escrevi?

Você não precisa ficar validando essas coisas, basta avaliar a fórmula atribuindo zero à todas as notas.

Um exemplo besta:

public class TesteScript {

  public static void main(String[] args) {
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine scriptEngine = scriptEngineManager
      .getEngineByName("javascript");


    while (true) {
      Scanner scanner = new Scanner(System.in);
      System.out.println("Digite a fórmula");
      String formula = scanner.nextLine();

      Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
      bindings.put("np1", 0);
      bindings.put("np2", 0);
      bindings.put("np3", 0);
      bindings.put("np4", 0);

      try {
        scriptEngine.eval(formula);
      } catch (ScriptException e) {
        System.out.println("Fórmula inválida");
      }
      System.out.println("Fórmula válida");
    }

  }

}

Isso pode validar qualquer maluquice que o usuário digitar como fórmula (só não irá tratar casos de divisão por zero, mas você pode dar uma arrumada pra prevenir isso).

R

Não queria empilhar eles, mas…Por exemplo, se o cara digitar os parênteses em lugares onde não deveriam estar…
Por exemplo, oque fiz em C++ foi para o seguinte exercício:


Daí que pensei assim…Alguma idéia de como fazer para verificar entao se o cara não digitou os parêntese no lugar onde nao deveria??

Rodrigo_Sasaki

Não queria empilhar eles, mas…Por exemplo, se o cara digitar os parênteses em lugares onde não deveriam estar…
Por exemplo, oque fiz em C++ foi para o seguinte exercício:


Daí que pensei assim…Alguma idéia de como fazer para verificar entao se o cara não digitou os parêntese no lugar onde nao deveria??
Siga a sugestão do Ataxexe :slight_smile: É o que eu faria hehehe.

Tente avaliar a expressão, se der certo, é uma expressão válida

R

Não queria empilhar eles, mas…Por exemplo, se o cara digitar os parênteses em lugares onde não deveriam estar…
Por exemplo, oque fiz em C++ foi para o seguinte exercício:


Daí que pensei assim…Alguma idéia de como fazer para verificar entao se o cara não digitou os parêntese no lugar onde nao deveria??
Siga a sugestão do Ataxexe :slight_smile: É o que eu faria hehehe.

Tente avaliar a expressão, se der certo, é uma expressão válida
hehehe, blz, vou ver como fazer a que o Ataxexe falou … Vlww

R

Não queria empilhar eles, mas…Por exemplo, se o cara digitar os parênteses em lugares onde não deveriam estar…
Por exemplo, oque fiz em C++ foi para o seguinte exercício:


Daí que pensei assim…Alguma idéia de como fazer para verificar entao se o cara não digitou os parêntese no lugar onde nao deveria??
Siga a sugestão do Ataxexe :slight_smile: É o que eu faria hehehe.

Tente avaliar a expressão, se der certo, é uma expressão válida
Bom dia Rodrigo, tudo certo ?? Bem, testei a sugestão do jeito do Ataxexe e funcionou.Abaixo a maneira como fiz:

public boolean verificaFormulAnual() throws ScriptException {
        String formula = crudObj.getFormulaAvaliacao();

        String REGEX = "(np\\d)";
        Double[] notas = {9.5, 9.3, 8.0, 8.8};

        StringBuffer novaFormula = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formula);

        int i = 0;
        while (buscador.find()) {
            buscador.appendReplacement(novaFormula, String.valueOf(notas[i++]));
        }
        buscador.appendTail(novaFormula);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultado = scriptEngine.eval(novaFormula.toString());

        if (resultado != null) {
            return true;
        } else {
            return false;
        }
    }

Mas, se eu quizer passar somente para testar um único valor para todas as notas ? ( pq nao sei qual a fórmula que a pessoa vai digitar. Então eu queria setar para todas as notas um único valor ao invés de um vetor de notas…Poderia dar uma ajuda aí?? Vlw

Ataxexe

Mais uma vez: leia o código que postei.

As notas devem ser atribuídas pelos bindings e não por uma regexp:

Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE); bindings.put("np1", 0); bindings.put("np2", 0); bindings.put("np3", 0); bindings.put("np4", 0);

E, se a fórmula for inválida sintaticamente, não será retornado null, será lançada uma exceção, que você deve tratar para retornar se a fórmula é válida ou inválida.

try { scriptEngine.eval(formula); } catch (ScriptException e) { System.out.println("Fórmula inválida"); } System.out.println("Fórmula válida");

Com algumas pequenas adaptações no código que postei você resolve seu problema. Eu tenho minhas dúvidas se esse seu código irá funcionar (a menos que você esteja capturando ScriptException para tratar.

Verificar o retorno da fórmula é uma adaptação válida para testar se não há algo de errado (você pode, por exemplo, atribuir a nota máxima para cada prova e testar se o valor da fórmula estará dentro do aceitável - seria estranho um aluno obter de média 8 com todas as notas 10). Você poderia até quebrar isso em dois passos: um para verificar sintaticamente a fórmula e outro para testar se ela está coesa.

R

Ataxexe:
Mais uma vez: leia o código que postei.

As notas devem ser atribuídas pelos bindings e não por uma regexp:

Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE); bindings.put("np1", 0); bindings.put("np2", 0); bindings.put("np3", 0); bindings.put("np4", 0);

E, se a fórmula for inválida sintaticamente, não será retornado null, será lançada uma exceção, que você deve tratar para retornar se a fórmula é válida ou inválida.

try { scriptEngine.eval(formula); } catch (ScriptException e) { System.out.println("Fórmula inválida"); } System.out.println("Fórmula válida");

Com algumas pequenas adaptações no código que postei você resolve seu problema. Eu tenho minhas dúvidas se esse seu código irá funcionar (a menos que você esteja capturando ScriptException para tratar.

Verificar o retorno da fórmula é uma adaptação válida para testar se não há algo de errado (você pode, por exemplo, atribuir a nota máxima para cada prova e testar se o valor da fórmula estará dentro do aceitável - seria estranho um aluno obter de média 8 com todas as notas 10). Você poderia até quebrar isso em dois passos: um para verificar sintaticamente a fórmula e outro para testar se ela está coesa.


Bom dia Ataxexe , tdo certo cara? Bem, consegui fazer da seguinte maneira:

public boolean verificaCoerenciaFormulAnual() throws ScriptException {
        String formulaAnual = crudObj.getFormulaAvaliacao();

        String REGEX = "(np\\d)";
        // Double[] notas = {9.5, 9.3, 8.0, 8.8};

        StringBuffer novaFormula = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formulaAnual);

        // int i = 0;
        while (buscador.find()) {
            buscador.appendReplacement(novaFormula, "10.0");
        }
        buscador.appendTail(novaFormula);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultado = scriptEngine.eval(novaFormula.toString());

        if (resultado != null) {
            return true;
        } else {
            return false;
        }
    }

A princípio funcionou…Agora estou vendo para testar outra fórmula, pois tenho a fórmula que pode contem nt e ne… Daí estou tentando usar assim:

String REGEX = "(nt\\d|ne\\d)";
...ou
 String REGEX = "(n[te]\\d)";

Só que n]ao está dando certo, pq ele não tá conseguindo montar a fórmula.Estou fazendo da mesma maneira do que fiz anteriormente…Poderia dar uma ajuda aí? Vlwww

R

Não queria empilhar eles, mas…Por exemplo, se o cara digitar os parênteses em lugares onde não deveriam estar…
Por exemplo, oque fiz em C++ foi para o seguinte exercício:


Daí que pensei assim…Alguma idéia de como fazer para verificar entao se o cara não digitou os parêntese no lugar onde nao deveria??
Siga a sugestão do Ataxexe :slight_smile: É o que eu faria hehehe.

Tente avaliar a expressão, se der certo, é uma expressão válida
Estou tentando fazer o seguinte para quando tenho a seguinte formula ( nt + ne) / 2 :

public boolean verificaCoerenciaFormulFinal() throws ScriptException {
        String formulaFinal = crudObj.getFormulAvalMediaFinal();
        // Exemplo de formula = (nt + ne)/2
        String REGEX = "(n[te]\\d)";
      
        StringBuffer novaFormula = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formulaFinal);

        while (buscador.find()) {
            buscador.appendReplacement(novaFormula, "10.0");
        }
        buscador.appendTail(novaFormula);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultado = scriptEngine.eval(novaFormula.toString());

        if (resultado != null) {
            return true;
        } else {
            return false;
        }
    }

Porém, ele não está conseguindo reconhecer e substituir…Poderia dar uma ajuda aí?? vLWW…

Rodrigo_Sasaki

Cara, se não tem o número, tem que tirar o \d :slight_smile: Isso indica que vai ter um número hehehe

R

Meu deusss!!! E eu aqui me batendo hehehehe…Mto obrigado pela ajuda aí Rodrigo, Vlw msm…
Também agradeço o aadario ( meu professor da universidade :slight_smile: ) e o Ataxexe Vlwwww

R

Boa tarde Rodrigo, tudo certo ?? Cara, preciso de uma ajuda novamente…
Antes, eu podia fazer o seguinte:

Pattern p = Pattern.compile("(\\d*|[+*/().-]|n[te]|\\s+)*");

Só que agora eu tbm quero digitar por exemplo np seguido de algum número na mesma fórmula. Tentei da seguinte maneira e nao obtive sucesso:

Pattern p = Pattern.compile("(\\d*|[+*/().-]|n[te]| np\\d+|\\s+)*");

Poderia dar uma ajuda aí ?? Se puder ajudar, agradeço mto…Vlw

Rodrigo_Sasaki

Tem um espaço ali no meio… Tire ele dali

R
Pattern p = Pattern.compile("(\\d*|[+*/().-]|n[te]|np\\d+|\\s+)*");

Só que ele está deixando passar nt1 por exemplo…O problema estaria aki???

private boolean formulaAvalMediaFinalVerdadeira() {
        Pattern p = Pattern.compile("(\\d*|[+*/().-]|n[te]|np\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulAvalMediaFinal());
        return m.matches();
    }


  public boolean verificaCoerenciaFormulFinal() throws ScriptException {
        String formulaFinal = crudObj.getFormulAvalMediaFinal();
        String REGEX = "(n[te]|np\\d)";
        StringBuffer novaFormulaFinal = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formulaFinal);

        while (buscador.find()) {
            buscador.appendReplacement(novaFormulaFinal, "10.0");
        }
        buscador.appendTail(novaFormulaFinal);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultadoFinal = scriptEngine.eval(novaFormulaFinal.toString());

        if (resultadoFinal != null) {
            return true;
        } else {
            return false;
        }
    }

Mais precisamente aki:

String REGEX = "(n[te]|np\\d)";

Nao estou conseguindo resolver…Se puder continuar ajudando, agradeço…Vlww cara

Rodrigo_Sasaki

Ele permite porque você colocou um \d* no começo. Isso permite qualquer número, em qualquer lugar. Então ficou meio confusa sua regex :slight_smile: Vai ter que repensá-la

R

Poderia dar uma ajuda com isso cara?? To apanhando a horas feio com ela já…Ela pode ter nt e ne SEM NÚMEROS mas tbm pode ter np COM números…Se puder ajudar, agradeceria mto Rodrigo…Vlw

Rodrigo_Sasaki

Vamos lá, vou te dar umas dicas, mas não vou fazer pra você :slight_smile:

\d -> Qualquer número
\D -> Qualquer coisa que não seja um número

As letras seriam as letras mesmo

R

Rodrigo Sasaki:
Vamos lá, vou te dar umas dicas, mas não vou fazer pra você :slight_smile:

\d -> Qualquer número
\D -> Qualquer coisa que não seja um número

As letras seriam as letras mesmo


vou tentar fazer aki, daki a poco posto o resultado…Vlw cara…

R

Rodrigo Sasaki:
Vamos lá, vou te dar umas dicas, mas não vou fazer pra você :slight_smile:

\d -> Qualquer número
\D -> Qualquer coisa que não seja um número

As letras seriam as letras mesmo


Cara, to tentando da seguinte maneira:

Pattern p = Pattern.compile("(\\d|[+*/().-]|\\D|n[te]|np\\d+|\\s+)*");

Tentei tbm:

Pattern p = Pattern.compile("(\\D|[+*/().-]|\\d|n[te]|np\\d+|\\s+)*");

E coloquei também parênteses entre meio…Mas não estou conseguindo…Poderia dar mais alguma dica ou ajuda?? Se puder ajudar, agradeço mtoo…To apanhando msm…Vlw cara…

Rodrigo_Sasaki

O detalhe importante é. após o nt ou ne não pode ter um número. É isso que sua expressão tem que declarar

R

Vamos lá mais uma vez para testes entao…:slight_smile:

R

To conseguindo deixar assim:

private boolean formulaAvalMediaFinalVerdadeira() {
        Pattern p = Pattern.compile("(\\d|[+*/().-]|n[te]\\D|np\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulAvalMediaFinal());
        return m.matches();
    }

public boolean verificaCoerenciaFormulFinal() throws ScriptException {
        String formulaFinal = crudObj.getFormulAvalMediaFinal();
        String REGEX = "(n[te]|np\\d)";
        StringBuffer novaFormulaFinal = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formulaFinal);

        while (buscador.find()) {
            buscador.appendReplacement(novaFormulaFinal, "10.0");
        }
        buscador.appendTail(novaFormulaFinal);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultadoFinal = scriptEngine.eval(novaFormulaFinal.toString());

        if (resultadoFinal != null) {
            return true;
        } else {
            return false;
        }
    }

Só que agora ele nao deixa por exemplo eu SOMENTE colocar o nt + ne, devo ter tbm um np1 junto por exemplo…Dicas?? Vlw Rodrigo…

Rodrigo_Sasaki

Não faz sentido, que expressão matemática você está usando pra testar?

R

Por exemplo:

(np1 + np2 + np3)/ 3  //deve deixar passar
(nt + ne)/2                //deveria deixar passar mas nao deixa
(nt + np1)/2              // somente assim deixa passar

Tipo, está deixando passar somente quando coloco um np ao menos na fórmula…Poderia dar uma mão aí?? Vlw…

Rodrigo_Sasaki

Testei aqui e ele validou as 3

R

Mas que diabos está acontecendo será??

R

Dessa maneira que eu estou validando está certo ?? Somente deixar que vá numeros quando o cara digita np: exemplo -> np1 + np2…
E deixar ele digitar tambem somente nt + ne SEM números???

Rodrigo_Sasaki
Sim, veja:
public class Teste {

	public static void main(String[] args) {
		validate("(np1 + np2 + np3)/ 3"); // true
		validate("(nt + ne)/2"); // true
		validate("(nt + np1)/2"); // true
		validate("(nt3 + np)"); // false
		validate("ne4"); // false
	}

	public static void validate(String str) {
		Pattern pattern = Pattern.compile("(\\d|[+*/().-]|n[te]\\D|np\\d+|\\s+)*");
		Matcher matcher = pattern.matcher(str);
		System.out.println(matcher.matches());
	}

}
R
Rodrigo Sasaki:
Sim, veja:
public class Teste {

	public static void main(String[] args) {
		validate("(np1 + np2 + np3)/ 3"); // true
		validate("(nt + ne)/2"); // true
		validate("(nt + np1)/2"); // true
		validate("(nt3 + np)"); // false
		validate("ne4"); // false
	}

	public static void validate(String str) {
		Pattern pattern = Pattern.compile("(\\d|[+*/().-]|n[te]\\D|np\\d+|\\s+)*");
		Matcher matcher = pattern.matcher(str);
		System.out.println(matcher.matches());
	}

}
Estou tentando colocar somente assim: nt + ne e ele nao está deixando.....
Rodrigo_Sasaki

Pra mim funciona :slight_smile: Sem brincadeira. Com o código que postei aí pra você

R

Ok, mas vc colocou assim:

(nt + ne)/2

Será que sem os () /2 , somente com nt + ne funciona no teu tbm ?? No meu nao tá funcionando…

Rodrigo_Sasaki

ah ta

“n[te]\D?”

R

Rodrigo Sasaki:
ah ta

“n[te]\D?”


Desculpe, mas não entendi…

R

Rodrigo Sasaki:
ah ta

“n[te]\D?”


Consegui, acredito que é somente colocar um “+” depois do D, correto? Vlw

Rodrigo_Sasaki

Não, no caso tem que ser a interrogação mesmo :slight_smile:

R

Bom dia Rodrigo, tdo certo ?? Desculpe, mas onde exatamente??

private boolean formulaAvalMediaFinalVerdadeira() {
        Pattern p = Pattern.compile("(\\d|[+*/().-]|n[te]\\D+|np\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulAvalMediaFinal());
        return m.matches();
    }

   public boolean verificaCoerenciaFormulFinal() throws ScriptException {
        String formulaFinal = crudObj.getFormulAvalMediaFinal();
        String REGEX = "(n[te]|np\\d)";
        StringBuffer novaFormulaFinal = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formulaFinal);

        while (buscador.find()) {
            buscador.appendReplacement(novaFormulaFinal, "10.0");
        }
        buscador.appendTail(novaFormulaFinal);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultadoFinal = scriptEngine.eval(novaFormulaFinal.toString());

        if (resultadoFinal != null) {
            return true;
        } else {
            return false;
        }
    }

A princípio tinha funcionado, mas porvias das dúvidas, queria saber onde devo alterar…Abc

Rodrigo_Sasaki

Só ver aonde eu coloquei a interrogação. logo após o \D

Ela indica que se existir algo após o nt ou ne, não pode ser um número.

R

Rodrigo Sasaki:
Só ver aonde eu coloquei a interrogação. logo após o \D

Ela indica que se existir algo após o nt ou ne, não pode ser um número.


Blz Rodrigo, mto obrigado pela ajuda…Vlw msm…Abc

R

Rodrigo Sasaki:
Só ver aonde eu coloquei a interrogação. logo após o \D

Ela indica que se existir algo após o nt ou ne, não pode ser um número.


Boa tarde Rodrigo, tdo certo ?? Cara, achei um furo nas validações…Seguinte, se o cara colocar na fórmula só () ele nao salva, mas dá o seguinte erro no console:

Grave:   javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: syntax error (<Unknown source>#1) in <Unknown source> at line number 1
.
.
.
Caused by: sun.org.mozilla.javascript.internal.EvaluatorException: syntax error (<Unknown source>#1)
	at sun.org.mozilla.javascript.internal.DefaultErrorReporter.runtimeError(DefaultErrorReporter.java:109)
	at sun.org.mozilla.javascript.internal.DefaultErrorReporter.error(DefaultErrorReporter.java:96)
	at sun.org.mozilla.javascript.internal.Parser.addError(Parser.java:231)
	at sun.org.mozilla.javascript.internal.Parser.addError(Parser.java:209)
	at sun.org.mozilla.javascript.internal.Parser.reportError(Parser.java:266)
	at sun.org.mozilla.javascript.internal.Parser.reportError(Parser.java:253)
	at sun.org.mozilla.javascript.internal.Parser.reportError(Parser.java:246)
	at sun.org.mozilla.javascript.internal.Parser.primaryExpr(Parser.java:2862)
	at sun.org.mozilla.javascript.internal.Parser.memberExpr(Parser.java:2459)
	at sun.org.mozilla.javascript.internal.Parser.unaryExpr(Parser.java:2369)
	at sun.org.mozilla.javascript.internal.Parser.mulExpr(Parser.java:2292)
	at sun.org.mozilla.javascript.internal.Parser.addExpr(Parser.java:2274)
	at sun.org.mozilla.javascript.internal.Parser.shiftExpr(Parser.java:2253)
	at sun.org.mozilla.javascript.internal.Parser.relExpr(Parser.java:2226)
	at sun.org.mozilla.javascript.internal.Parser.eqExpr(Parser.java:2196)
	at sun.org.mozilla.javascript.internal.Parser.bitAndExpr(Parser.java:2183)
	at sun.org.mozilla.javascript.internal.Parser.bitXorExpr(Parser.java:2170)
	at sun.org.mozilla.javascript.internal.Parser.bitOrExpr(Parser.java:2157)
	at sun.org.mozilla.javascript.internal.Parser.andExpr(Parser.java:2144)
	at sun.org.mozilla.javascript.internal.Parser.orExpr(Parser.java:2131)
	at sun.org.mozilla.javascript.internal.Parser.condExpr(Parser.java:2107)
	at sun.org.mozilla.javascript.internal.Parser.assignExpr(Parser.java:2076)
	at sun.org.mozilla.javascript.internal.Parser.expr(Parser.java:2053)
	at sun.org.mozilla.javascript.internal.Parser.parenExpr(Parser.java:2875)
	at sun.org.mozilla.javascript.internal.Parser.primaryExpr(Parser.java:2810)
	at sun.org.mozilla.javascript.internal.Parser.memberExpr(Parser.java:2459)
	at sun.org.mozilla.javascript.internal.Parser.unaryExpr(Parser.java:2369)
	at sun.org.mozilla.javascript.internal.Parser.mulExpr(Parser.java:2292)
	at sun.org.mozilla.javascript.internal.Parser.addExpr(Parser.java:2274)
	at sun.org.mozilla.javascript.internal.Parser.shiftExpr(Parser.java:2253)
	at sun.org.mozilla.javascript.internal.Parser.relExpr(Parser.java:2226)
	at sun.org.mozilla.javascript.internal.Parser.eqExpr(Parser.java:2196)
	at sun.org.mozilla.javascript.internal.Parser.bitAndExpr(Parser.java:2183)
	at sun.org.mozilla.javascript.internal.Parser.bitXorExpr(Parser.java:2170)
	at sun.org.mozilla.javascript.internal.Parser.bitOrExpr(Parser.java:2157)
	at sun.org.mozilla.javascript.internal.Parser.andExpr(Parser.java:2144)
	at sun.org.mozilla.javascript.internal.Parser.orExpr(Parser.java:2131)
	at sun.org.mozilla.javascript.internal.Parser.condExpr(Parser.java:2107)
	at sun.org.mozilla.javascript.internal.Parser.assignExpr(Parser.java:2076)
	at sun.org.mozilla.javascript.internal.Parser.expr(Parser.java:2053)
	at sun.org.mozilla.javascript.internal.Parser.statementHelper(Parser.java:1082)
	at sun.org.mozilla.javascript.internal.Parser.statement(Parser.java:944)
	at sun.org.mozilla.javascript.internal.Parser.parse(Parser.java:569)
	at sun.org.mozilla.javascript.internal.Parser.parse(Parser.java:531)
	at sun.org.mozilla.javascript.internal.Context.compileImpl(Context.java:2428)
	at sun.org.mozilla.javascript.internal.Context.compileReader(Context.java:1345)
	at sun.org.mozilla.javascript.internal.Context.compileReader(Context.java:1317)
	at sun.org.mozilla.javascript.internal.Context.evaluateReader(Context.java:1156)
	at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:214)
	... 80 more

Poderia dar uma ajuda aí?
O teste tá da seguinte maneira:

private boolean formulaAvalMediaFinalVerdadeira() {
        Pattern p = Pattern.compile("(\\d|[+*/().-]|n[te]\\D+|np\\d+|\\s+)*");
        Matcher m = p.matcher(crudObj.getFormulAvalMediaFinal());
        return m.matches();
    }

    public boolean verificaCoerenciaFormulFinal() throws ScriptException {
        String formulaFinal = crudObj.getFormulAvalMediaFinal();
        String REGEX = "(n[te]|np\\d)";
        StringBuffer novaFormulaFinal = new StringBuffer();
        Matcher buscador = Pattern.compile(REGEX).matcher(formulaFinal);

        while (buscador.find()) {
            buscador.appendReplacement(novaFormulaFinal, "10.0");
        }
        buscador.appendTail(novaFormulaFinal);
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        Object resultadoFinal = scriptEngine.eval(novaFormulaFinal.toString());

        if (resultadoFinal != null) {
            return true;
        } else {
            return false;
        }
    }

Se puder ajudar, agradeço mto…Vlwww

Criado 16 de setembro de 2013
Ultima resposta 11 de out. de 2013
Respostas 59
Participantes 3