IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java正则校验的坑&正则校验公式正确性 -> 正文阅读

[Java知识库]java正则校验的坑&正则校验公式正确性

1,首先讲一下java中正则表达式的坑

举例: 欲校验公式(+x+1)合法性,正则表达式\([+\-*/]+,使用菜鸟在线正则校验就可以匹配,而使用java的String.matches方式竟然匹配不成功:

public static void main(String[] args) {
    String express = "(+x+1)";
    String regex = "\\([+\\-*/]+";
    
    System.out.println("String matches result:" + express.matches(regex));
}

在这里插入图片描述

然后各种百度,终于找到了解决办法,使用以下这种方式可以正确匹配:

public static void main(String[] args) {
    String express = "(+x+1)";
    String regex = "\\([+\\-*/]+";
    
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(express);
    System.out.println("pattern-matcher result:" + m.find());
}

在这里插入图片描述

2,需求:校验用户输入的公式是否合法

具体限制:公式中只能包含±*/()以及数字,最多只会含有一个未知数,用X表示,可以是两位小数
我的实现如下(注释写的很详细,保姆式笔记,以后忘了反复看方便记忆。如果大家有更好的更简便的方法请指教哈):

	public static boolean check(String expression) {
        //错误情况,小数点后最多2位
        // \\.代表小数点;\\d表示数字;[]表示内部符号只出现其中一个,此处[\\d]就表示一个数字;{3,}表示前边的字符出现最少3次
        if (FormulaCheckUtil.match("\\.[\\d]{3,}", expression)) {
            System.out.println("公式有误!小数点后最多2位:" + expression);
            return false;
        }
        //错误情况,小数点后边不是数字
        // \\.代表小数点;\\d表示数字;[]中的^代表取反;此处[^\\d]表示非数字
        if (FormulaCheckUtil.match("\\.[^\\d]", expression)) {
            System.out.println("公式有误!小数点后边不是数字:" + expression);
            return false;
        }
        //错误情况,小数点前边不是数字
        //同上
        if (FormulaCheckUtil.match("[^\\d]\\.", expression)) {
            System.out.println("公式有误!小数点前边不是数字:" + expression);
            return false;
        }
        //错误情况,空格前后都是数字(数字被空格分隔)
        // \\d表示数字;\\s(小写字母s)表示空格;+表示前边的字符出现一次或多次
        if (FormulaCheckUtil.match("\\d[\\s]+\\d", expression)) {
            System.out.println("公式有误!数字不连续:" + expression);
            return false;
        }

        String exprTrim = expression.replaceAll(" ", "").toUpperCase();

        // 错误情况,空字符串
        if (StringUtils.EMPTY.equals(exprTrim)) {
            System.out.println("公式有误!表达式不能为空!");
            return false;
        }

        //公式中只能包含 +-*/()X
        // []中的内容依次是“取反符号、加、减、乘、除、左小括号、右小括号、数字、小数点”,
        //其中“减号、左右小括号、小数点”需要转义,因此前边都有两条反斜杠,然后[]最前边是取反符号^,表示非以上字符;
        // []后边的+表示前边的字符出现一次或多次
        if (FormulaCheckUtil.match("[^+\\-*/\\(\\)X\\d\\.]+", exprTrim)) {
            System.out.println("公式有误!公式中只能包含 +-*/()X和数字");
            return false;
        }
        //公式中不包含X时,只支持输入数字,不支持输入运算符
        if (!exprTrim.contains("X")) {
        	// \\d-数字 “.”-小数点  “+”-出现一次或多次
            String regex = "[\\d.]+";
            if (!exprTrim.matches(regex)) {
                System.out.println("公式有误!公式中不包含X时,只支持输入数字!");
                return false;
            }
        }

        // 错误情况,运算符连续
        // []中的“加减乘除”符号连续出现2次以上
        if (exprTrim.matches("[+\\-*/]{2,}")) {
            System.out.println("公式有误!运算符不能连续!");
            return false;
        }

        // 空括号 \\(-转义左括号   \\)-转义有括号
        if (exprTrim.matches("\\(\\)")) {
            System.out.println("公式有误!不能含有空括号!");
            return false;
        }

        // 错误情况,括号不配对
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < exprTrim.length(); i++) {
            char item = exprTrim.charAt(i);
            if ('(' == item) {
                stack.push('(');
            } else if (')' == item) {
                if (!stack.isEmpty()){
                    stack.pop();
                } else {
                    System.out.println("公式有误!括号不配对!");
                    return false;
                }
            }
        }
        if (!stack.isEmpty()) {
            System.out.println("公式有误!括号不配对!");
            return false;
        }

        // 错误情况,X连续出现两次以上
        if (exprTrim.matches("X{2}")) {
            System.out.println("公式有误!未知数不能连续出现!");
            return false;
        }

        // 错误情况,X后面不是运算符或")"
        // []内取反符号后依次为“加、减、乘、除、左括号”,表示非以上字符;表达式匹配的是“X后边非以上字符”
        if (FormulaCheckUtil.match("X[^+\\-*/)]", exprTrim)) {
            System.out.println("公式有误!X后面只能是运算符或\")\"");
            return false;
        }
        // 错误情况 X前边不是"("或运算符
        // []内取反符号后依次为“右括号、加、减、乘、除”,表示非以上字符;表达式匹配的是“X前边非以上字符”
        if (FormulaCheckUtil.match("[^(+\\-*/]X", exprTrim)) {
            System.out.println("公式有误!X前边只能是\"(\"或运算符");
            return false;
        }

        if (exprTrim.contains("(")) {
            // 错误情况,(后面是运算符
            // "\\("表示左小括号;[]内依次为“右括号、加、减、乘、除”;[]后有一个+ 表示前边一个字符出现一次或多次;
            // 表达式匹配的是“左括号后边是以上字符”
            if (exprTrim.matches("\\([+\\-*/]+")) {
                System.out.println("公式有误!\"(\"后面不能是运算符");
                return false;
            }

            // 错误情况,)前面是运算符
            // 同上
            if (exprTrim.matches("[+\\-*/]+\\)")) {
                System.out.println("公式有误!\")\"前面不能是运算符");
                return false;
            }

            // 以 "(" 开头, 或者 "(" 前边是运算符,否则错误
            // []内取反符号^后边依次为“左括号、加、减、乘、除”符号,[]内表达式部分表示非以上字符;“\\(”表示左括号
            // 表达式含义为左括号“(”前边为 非以上字符
            if (!exprTrim.startsWith("(") && FormulaCheckUtil.match("[^(+\\-*/]\\(", exprTrim)) {
                System.out.println("公式有误!\"(\"前边只能是\"(+-*/\"!");
                return false;
            }

            // 以 ")" 结尾或者 ")" 后边是运算符,否则错误
            // 同上
            if (!exprTrim.endsWith(")") && FormulaCheckUtil.match("\\)[^)+\\-*/]", exprTrim)) {
                System.out.println("公式有误!\")\"后边只能是\")+-*/\"!");
                return false;
            }
        }
		
		//将“加减乘除”符号替换为同一个字符
        String temp = exprTrim.replaceAll("[+\\-*/]", "`");
        if (temp.startsWith("`")) {
            System.out.println("公式有误!不能以运算符开头!");
            return false;
        }
        return true;
    }

	private static boolean match(String regex, String express) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(express);
        return m.find();
    }

参考博客:

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:49:43  更:2022-03-31 23:50:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:26:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码