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());
}

在这里插入图片描述

现在知道两者的区别了!!!

str.matches(String regex) 方法是检测全字符串是否匹配给定的正则表达式,此方法与Pattern.matches(regex, str)产生的结果完全相同;
而Pattern-Matcher find 方式是在字符串中查找匹配正则,如果查找到了匹配的局部字符串,就返回true

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

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

	public class FormulaCheckUtil {
		/**
	     * 验证四则运算表达式是否准确
	     * 注意:此处正则表达式都应【写错误形式】,而非【正确形式然后取反】,否则只要有一次匹配成功就返回true了
	     * @param expression 字符串公式表达式
	     */
		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 (FormulaCheckUtil.match("[+\\-*/]{2,}", exprTrim)) {
	            System.out.println("公式有误!运算符不能连续!");
	            return false;
	        }
	
	        // 空括号 \\(-转义左括号   \\)-转义有括号
	        if (FormulaCheckUtil.match("\\(\\)", exprTrim)) {
	            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 (FormulaCheckUtil.match("X{2}", exprTrim)) {
	            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 (FormulaCheckUtil.match("\\([+\\-*/]+", exprTrim)) {
	                System.out.println("公式有误!\"(\"后面不能是运算符");
	                return false;
	            }
	
	            // 错误情况,)前面是运算符
	            // 同上
	            if (FormulaCheckUtil.match("[+\\-*/]+\\)", exprTrim)) {
	                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中,可以使用正则表达式来校验文件地址的合法性。文件地址的合法性通常包括以下几个方面: 1. 文件路径的格式正确。 2. 文件路径中不包含非法字符。 3. 文件路径的各个部分(如目录名、文件名)符合操作系统的命名规则。 以下是一个示例代码,展示了如何使用正则表达式来校验文件地址的合法性: ```java import java.util.regex.Matcher; import java.util.regex.Pattern; public class FilePathValidator { // 正则表达式示例(Windows和Unix文件路径) private static final String WINDOWS_FILE_PATH_REGEX = &quot;^[a-zA-Z]:\\\\(?:[^\\/:*?\&quot;&lt;&gt;|\r\n]+\\\\)*[^\\/:*?\&quot;&lt;&gt;|\r\n]*$&quot;; private static final String UNIX_FILE_PATH_REGEX = &quot;^(/[^/ ]*)+/?$&quot;; // 方法:校验文件路径 public static boolean isValidFilePath(String filePath) { // 根据操作系统选择正则表达式 String os = System.getProperty(&quot;os.name&quot;).toLowerCase(); String filePathRegex; if (os.contains(&quot;win&quot;)) { filePathRegex = WINDOWS_FILE_PATH_REGEX; } else { filePathRegex = UNIX_FILE_PATH_REGEX; } Pattern pattern = Pattern.compile(filePathRegex); Matcher matcher = pattern.matcher(filePath); return matcher.matches(); } // 主方法:测试校验 public static void main(String[] args) { String[] testPaths = { &quot;C:\\Program Files\\Java\\jdk1.8.0_221&quot;, &quot;/usr/local/bin&quot;, &quot;C:\\Invalid Path\\*&quot;, &quot;/invalid path/&quot;, &quot;D:/valid/path/file.txt&quot;, &quot;/valid/path/file.txt&quot; }; for (String path : testPaths) { System.out.println(&quot;Path: &quot; + path + &quot; is valid: &quot; + isValidFilePath(path)); } } } ``` 在这个示例中,我们定义了两个正则表达式,一个用于Windows文件路径,另一个用于Unix文件路径。在`isValidFilePath`方法中,我们根据当前操作系统选择合适的正则表达式,并使用`Pattern`和`Matcher`类来校验文件路径的合法性。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值