编程算法基础-2.5正则表达式进阶
2.5正则表达式进阶正则表达式的功能相当强大 Java 提供Pattern,Matcher类 Pattern:代表正则表达式本身 对正则进行预先编译处理 提高处理的效率 Matcher:代表正则匹配的结果 实现更加复杂的管理 如:进行子组的管理 四则运算-括号优先Pattern Matcher 串 解析 运算符操作数 运算符运算的先后次序关系 正常思路:双栈求解四则运算(逆波兰表达式) 这里不讨论逆波兰表达式,仅仅用正则来解决,虽然效率可能不是最高的 最内层括号先求值,获得最内层括号,正则匹配问题 String s = “2+3*(5*(12-6))”; Pattern pt = Pattern.compile() /* * 带有括号的计算 * 求四则运算表达式的值 Pattern Matcher 只有加减乘。除法具有特殊性 */ package RegularExpression; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Equation { public static void main(String[] args) { String s = "2+3*(5*(12-6))"; Pattern pt = Pattern.compile("(([^()]*))"); Matcher m = pt.matcher(s); if(m.find()){ System.out.println(m.group(1));//直接提取子组 System.out.println(m.start()); System.out.println(m.end()); } } } 12-6 7 13
四则运算-没有括号乘法优先package RegularExpression; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Equation2 { public static void main(String[] args) { String s = "2+3*15*2-7"; Pattern pt = Pattern.compile("([0-9]+)(*)([0-9]+)"); Matcher m = pt.matcher(s); if(m.find()){ System.out.println(m.group()); System.out.println(m.group(1)); System.out.println(m.group(2)); System.out.println(m.group(3)); } } } 3*15 3 * 15 完整的示例代码如下: package RegularExpression; /* 计算表达式的值(假设只有加法、减法、乘法) 23+15-16*(25+(6-3)+9*2) */ import java.util.regex.*; public class T1 { // 计算没有括号的表达式 static String calcuNoParen(String s) { if (s.length() < 1) return s; // 先把所有乘法消除 Pattern pat = Pattern.compile("([0-9]+)*([0-9]+)"); while (true) { Matcher mc = pat.matcher(s); if (mc.find() == false) break; // 已经没有乘法了 int res = Integer.parseInt(mc.group(1)) * Integer.parseInt(mc.group(2)); s = s.replace(mc.group(),res + ""); // 注意这里不能用replaceAll } // 再从左到右消除所有加法或减法 pat = Pattern.compile("([0-9]+)([+-])([0-9]+)"); while (true) { Matcher mc = pat.matcher(s); if (mc.find() == false) break; // 已经没有运算符了 int res = 0; if (mc.group(2).equals("+")) res = Integer.parseInt(mc.group(1)) + Integer.parseInt(mc.group(3)); else res = Integer.parseInt(mc.group(1)) - Integer.parseInt(mc.group(3)); s = s.replace(mc.group(),res + ""); // 注意这里不能用replaceAll } return s; } // 计算可能含有括号的表达式 static String calcu(String s) { s = s.replaceAll(" +",""); // 消除空格 Pattern pat = Pattern.compile("(([^()]*))"); while (true) { Matcher mc = pat.matcher(s); if (mc.find() == false) break; // 把括号内先计算,然后消除括号 s = s.replace(mc.group(),calcuNoParen(mc.group(1))); } return calcuNoParen(s); } public static void main(String[] args) { /* * String s = "23+15-16*(25+(6-3*2*1)+9*2)"; * * //任务:找到最内层括号中的内容,计算后替换掉 */ System.out.println(calcu("5 + 3 * 2 * (2+2-3) - 1")); } } 10 上述代码除了没有实现除法外,还不能有负号
展开串实际开发中,常常会出现用到一批文件,而这些文件的文件名有某种规律,我们在表述的时候,往往习惯简写,但这样程序又不好识别。 比如: c:/abc/xyz/k[11..19].dat 实际表示的就是: c:/abc/xyz/k11.dat c:/abc/xyz/k12.dat c:/abc/xyz/k13.dat c:/abc/xyz/k14.dat c:/abc/xyz/k15.dat c:/abc/xyz/k16.dat c:/abc/xyz/k17.dat c:/abc/xyz/k18.dat c:/abc/xyz/k19.dat 本题目要求是:给定一个含有简写的串,要求展开为所有文件名。 简写的格式为:[整数..整数] /* * 展开串 实际开发中,常常会出现用到一批文件,而这些文件的文件名有某种规律,我们在表述的时候,往往习惯简写,但这样程序又不好识别。 比如: c:/abc/xyz/k[11..19].dat 实际表示的就是: c:/abc/xyz/k11.dat c:/abc/xyz/k12.dat c:/abc/xyz/k13.dat c:/abc/xyz/k14.dat c:/abc/xyz/k15.dat c:/abc/xyz/k16.dat c:/abc/xyz/k17.dat c:/abc/xyz/k18.dat c:/abc/xyz/k19.dat 本题目要求是:给定一个含有简写的串,要求展开为所有文件名。 简写的格式为:[整数..整数] */ package RegularExpression; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UnfoldString { public static void main(String[] args) { String s = "c:/abc/xyz/k[11..19].dat"; for(int i=0;i<unfoldName(s).size();i++){ System.out.println(unfoldName(s).get(i)); } } public static List<String> unfoldName(String s){ ArrayList<String> list = new ArrayList<String>(); Pattern pt = Pattern.compile("[([0-9]+)..([0-9]+)]");//匹配[11..19] Matcher m = pt.matcher(s); if(m.find()){ int start = Integer.valueOf(m.group(1)); int end = Integer.valueOf(m.group(2)); for(int i=start;i<=end;i++){ list.add(s.replace(m.group(),String.valueOf(i)));//用i替换[11..19] } } return list; } } c:/abc/xyz/k11.dat c:/abc/xyz/k12.dat c:/abc/xyz/k13.dat c:/abc/xyz/k14.dat c:/abc/xyz/k15.dat c:/abc/xyz/k16.dat c:/abc/xyz/k17.dat c:/abc/xyz/k18.dat c:/abc/xyz/k19.dat (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |