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) {
if (FormulaCheckUtil.match("\\.[\\d]{3,}", expression)) {
System.out.println("公式有误!小数点后最多2位:" + expression);
return false;
}
if (FormulaCheckUtil.match("\\.[^\\d]", expression)) {
System.out.println("公式有误!小数点后边不是数字:" + expression);
return false;
}
if (FormulaCheckUtil.match("[^\\d]\\.", expression)) {
System.out.println("公式有误!小数点前边不是数字:" + expression);
return false;
}
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;
}
if (FormulaCheckUtil.match("[^+\\-*/\\(\\)X\\d\\.]+", exprTrim)) {
System.out.println("公式有误!公式中只能包含 +-*/()X和数字");
return false;
}
if (!exprTrim.contains("X")) {
String regex = "[\\d.]+";
if (!exprTrim.matches(regex)) {
System.out.println("公式有误!公式中不包含X时,只支持输入数字!");
return false;
}
}
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;
}
if (exprTrim.matches("X{2}")) {
System.out.println("公式有误!未知数不能连续出现!");
return false;
}
if (FormulaCheckUtil.match("X[^+\\-*/)]", exprTrim)) {
System.out.println("公式有误!X后面只能是运算符或\")\"");
return false;
}
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();
}
参考博客:
|