有一个关于Java Regex的问题

xiaoyin35 2021-02-20 09:03:40
我要实现一个效果:
控制台:
2012.223+3132.21*{91-[33/(23+43.312)]+31}-99
=382 484.1065722
输入表达式,非法回复=Error,合法回复结果:
现在已经实现匹配数字(可带+/-、小数和小数点等,不可带i(虚数))
ExpressionEvaluation.Main.java

package ExpressionEvaluation;

import java.util.*;
import java.util.regex.*;

import tree.*; // tree.Node.java和tree.Tree.java自己编的

public class Main
{
public static void output(String line)
{
System.out.println(line);
}
public static String input()
{
Scanner s = new Scanner(System.in);
String line = s.nextLine();
return line;
}
public static boolean match(Pattern ptn, String str)
{
Matcher m = ptn.matcher(str);
boolean flag = m.matches();
return flag;
}
public static void main(String args[])
{
String number_str = "(\\+|-)?([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])";
Pattern number = Pattern.compile(number_str);

String str = input();

System.out.println(match(number, str));
}
}

tree.Node.java

package tree;

import java.util.ArrayList;

public class Node<type>
{
public type data = null;
public Node<type> father = null;
public ArrayList<Node<type>> children = new ArrayList<Node<type>>();
@Override
public String toString()
{
return data.toString();
}
public void addChild(Node<type> child)
{
children.add(child);
}
public void addChild(Node<type> child, int index)
{
children.add(index, child);
}
public void setChild(Node<type> child, int index)
{
children.set(index, child);
}
public Node<type> getChild(int index)
{
return children.get(index);
}
}

tree.Tree.java

package tree;

import java.util.ArrayList;
import tree.Node;

public class Tree<type>
{
private Node<type> root = new Node<type>();
public Tree()
{
// pass
}
public Tree(type rdata)
{
root.data = rdata;
}
public Node<type> getRoot()
{
return root;
}
}

...全文
412 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
[PE]经典八炮 2022-10-23
  • 打赏
  • 举报
回复

问题解决了吗

xiaoyin35 2021-03-05
  • 打赏
  • 举报
回复
到底是啥??
xiaoyin35 2021-02-25
  • 打赏
  • 举报
回复
我是有一个Node.java和Tree.java
i__0o0__ 2021-02-22
  • 打赏
  • 举报
回复
之前写过一个分析sql语句的where条件,组织成树结构的,跟计算式很相似,可惜代码找不到了, 如果有需要,可以私信我,给你讲一下思路
i__0o0__ 2021-02-22
  • 打赏
  • 举报
回复
这是自己定义了一个数字计算规则,需要一个编译器,对输入的算式进行校验及计算, 可以把算式分析成树结构
lin351550660 2021-02-21
  • 打赏
  • 举报
回复
我们自己做的 公式检查 给你参考一下
lin351550660 2021-02-21
  • 打赏
  • 举报
回复
package com.yiweikeji.question.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.script.ScriptUtil;
import com.yiweikeji.question.model.Question;
import com.yiweikeji.question.model.QuestionOption;
import com.yiweikeji.question.web.vo.QuestionVo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Fcx
 * @Date: 2020/3/18 10:15
 * @Version 1.0
 */
public class CheckQuestion {

    /**
     * 检查题目答案是否正确
     *
     * @param question
     * @return
     */
    public static boolean check(QuestionVo question) {
        if (2 != question.getQuestionType()
                || 1 != question.getTopicType()) {
            // 免检产品
            return true;
        }

        String questionName = question.getName();
        String optionContent = null;
        List<QuestionOption> options = question.getOptions();
        if (CollUtil.isEmpty(options)) {
            throw new RuntimeException("选项缺失");
        }
        // 拿到正确答案
        for (QuestionOption option : options) {
            if (option.getAnswerType().equals(question.getAnswer().toString())) {
                optionContent = option.getContent();
                break;
            }
        }
        return check(questionName, optionContent);
    }
    /**
     * 检查题目答案是否正确
     *
     * @param question
     * @return
     */
    public static boolean check(Question question) {
        if (2 != question.getQuestionType()
                || 1 != question.getTopicType()) {
            // 免检产品
            return true;
        }

        String questionName = question.getName();
        String optionContent = null;
        List<QuestionOption> options = question.getOptions();
        if (CollUtil.isEmpty(options)) {
            throw new RuntimeException("选项缺失");
        }
        // 拿到正确答案
        for (QuestionOption option : options) {
            if (option.getAnswerType().equals(question.getAnswer().toString())) {
                optionContent = option.getContent();
                break;
            }
        }
        return check(questionName, optionContent);
    }

    public static boolean check(String questionName, String optionContent) {
        if (StrUtil.isEmpty(optionContent)) {
            throw new RuntimeException("缺少正确选项");
        }

        String replaceDicStr = "{'➗':'/', '÷':'/', '×':'*', '=':'=', '米':'', '元':'', '>':'>', '<':'<', '+':'+', '-':'-', '(':'(', ')': ')', 'x':'X', ',':','}";

        ArrayList<String> continueStr = new ArrayList<>();
        continueStr.add("当");
        continueStr.add("时");
        continueStr.add("则");
        continueStr.add("约");
        continueStr.add("化");
        continueStr.add("简");
        continueStr.add("已知");
        continueStr.add("求");
        continueStr.add("a");
        continueStr.add("b");
        continueStr.add("c");
        continueStr.add("m");
        continueStr.add(":");
        HashMap replaceDic = JSONUtil.toBean(replaceDicStr, HashMap.class);
        // 11 + 2 =
        questionName = replaceForMap(questionName, replaceDic);

        // 跳过关键词
        for (String s : continueStr) {
            if (questionName.contains(s)) {
                // 免检产品
                return true;
            }
        }

        // 去掉结尾的 =
        if (StrUtil.endWith(questionName, "=")) {
            questionName = questionName.replace("=", "");
        }

        // %
        if (questionName.contains("%")) {
            // 转换成带括号的除法
            questionName = buildPerCent(questionName);
        }
        if (optionContent.contains("%")) {
            optionContent = buildPerCent(optionContent);
        }

        /**
         * 开始计算
         */
        String format = "#.###";
        // 答案的小数位长度格式化
        // 问题里没有 = 或者以 = 结尾
        boolean b = !questionName.contains("=")
                || questionName.endsWith("=");
        if (b && !LocalStrUtil.isArabicNumerals(questionName)
                && LocalStrUtil.isArabicNumerals(optionContent)) {
            // 答案是数字,那就看有几位小数
            if (optionContent.contains(".")) {
                // 取最后一个.的索引
                format = "#.";
                String s = StrUtil.subAfter(optionContent, ".", true);
                for (int i = 0; i < s.length(); i++) {
                    format = format + "#";
                }

            }
        }

        // 含有 []  有中括号的,先算中括号里面的算式    如 30 × [(104  -  94) × 13] =
        if (questionName.contains("[")
                && questionName.contains("]")) {
            String inQuestionName = StrUtil.subBetween(questionName, "[", "]");
            BigDecimal mathValue = getMathValue(inQuestionName, format);
            questionName = questionName.replace("[" + inQuestionName + "]", mathValue.toString());
            // return compareForBracket(questionName, optionContent);
        }

        // 含有 () X   --------------- 4 ÷ (  )= 10   4(X+3)=24
        if (StrUtil.containsAny(questionName, "()", "X")) {
            return compareForBracket(questionName, optionContent, format);
        }
        // 含有 〇  ----------------  17  -  3   〇   10
        if (questionName.contains("〇")) {
            return compareForCircle(questionName, optionContent, format);
        }
        // 普通四则运算  +-*/     3/6 + 2/6 =
        BigDecimal mathValue = getMathValue(questionName, format);
        if (NumberUtil.isNumber(optionContent)) {
            return 0 == mathValue.compareTo(new BigDecimal(optionContent));
        }
        // 有余数, 特殊处理
        if (optionContent.contains("...") && questionName.contains("/")) {
            String[] split = questionName.split("/");
            BigDecimal mathValue1 = getMathValue(split[0], format);
            BigDecimal mathValue2 = getMathValue(split[1], format);
            // 整数
            int intNum = mathValue1.divide(mathValue2, BigDecimal.ROUND_DOWN).intValue();
            // 小数
            int floatNum = mathValue1.subtract(BigDecimal.valueOf(intNum).multiply(mathValue2)).intValue();

            String s = intNum + "..." + floatNum;
            return s.equals(optionContent);
        }
        return 0 == mathValue.compareTo(getMathValue(optionContent, format));
    }

    /**
     * 百分号转换    3÷3%  ->   3÷(3/100)
     *
     * @param source
     * @return
     */
    private static String buildPerCent(String source) {
        String[] split = source.split("%");
        for (int i = 0; i < split.length; i++) {
            String lastNumber = LocalStrUtil.cutLastNumber(split[i]);
            source = source.replace(lastNumber + "%", "(" + lastNumber + "/100)");
        }
        return source;
    }

    /**
     * ()   8  - (  )= 4  4   return true
     *
     * @param questionName
     * @param option
     * @return
     */
    private static boolean compareForBracket(String questionName, String option, String format) {
        option = option.replace("=", "=")
                .replace(">", ">")
                .replace("<", "<");

        // X 前后 如果直接跟着数字,那就填充乘号  3.5X + 0.5X = 12.8  改为 3.5*X + 0.5*X = 12.8
        if (questionName.contains("X")) {
            StringBuilder newQuestionName = new StringBuilder();
            String[] xes = questionName.split("X");
            for (int i = 0; i < xes.length - 1; i++) {
                String x = xes[i];
                String s = StrUtil.subSufByLength(xes[i], 1);
                if (StrUtil.isNotEmpty(s)) {
                    if (NumberUtil.isNumber(s)) {
                        newQuestionName
                                .append(x)
                                .append("*")
                                .append("X");
                    }
                }
            }
            if (StrUtil.isNotEmpty(newQuestionName)) {
                newQuestionName.append(xes[xes.length - 1]);
                questionName = newQuestionName.toString();
            }
        }

        questionName = questionName.replace("()", option)
                .replace("X", option);
        String s = StrUtil.subPre(questionName, questionName.indexOf("="));
        BigDecimal mathValue = getMathValue(s, format);
        String[] compareOperators = new String[]{"=", ">", "<"};
        String s1 = null;
        for (String compareOperator : compareOperators) {
            if (questionName.contains(compareOperator)) {
                s1 = StrUtil.subSuf(questionName, questionName.indexOf(compareOperator) + 1);
                break;
            }
        }
        if (NumberUtil.isNumber(s1)) {
            return 0 == mathValue.compareTo(new BigDecimal(s1));
        }
        return 0 == mathValue.compareTo(getMathValue(s1, format));
    }

    /**
     * 〇    17  -  3   〇   10    >  return  true
     *
     * @param questionName
     * @param option
     * @return
     */
    private static boolean compareForCircle(String questionName, String option, String format) {
        option = option.replace("=", "=")
                .replace(">", ">")
                .replace("<", "<");
        questionName = questionName.replace("〇", option);
        String s = StrUtil.subPre(questionName, questionName.indexOf(option));
        BigDecimal mathValue = getMathValue(s, format);
        String[] compareOperators = new String[]{"=", ">", "<"};
        BigDecimal mathValue1 = null;
        for (String compareOperator : compareOperators) {
            if (questionName.contains(compareOperator)) {
                String s1 = StrUtil.subSuf(questionName, questionName.indexOf(compareOperator) + 1);
                if (NumberUtil.isNumber(s1)) {
                    mathValue1 = new BigDecimal(s1);
                } else {
                    mathValue1 = getMathValue(s1, format);
                }
            }
        }

        if ("=".equals(option)) {
            return 0 == mathValue.compareTo(math

58,452

社区成员

发帖
与我相关
我的任务
社区描述
Java Eclipse
社区管理员
  • Eclipse
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧