写这个博客主要是稍微系统的学一下Java的正则表达式吧。还有因为,之前遇到一个问题,没有办法解决,我来了一招反向匹配,骚的我自己都受不了。然而,身为一个代码猴,我不应该这样不求甚解。Java中不可能没有,我要的方法。(如果没有,我立马转学Cshit去。)
扯淡结束,先描述一下我最开始遇到的问题吧。
从前有一个前端小姐姐向后端传送了一个时间的数据类型,然而她传给我的是如下格式:2017年08月18日15时41分
当时我见到这种格式我就懵逼了,百度了许久也没有找到解决方法。我无法将这个String转成Date。
于是我就想到用正则表达式来获得String里面的数字。(2017, 08, 18, 15, 41)
然后new 一个Date数据类型,然后存到数据库中。
我的这个想法是好的,然而显示确实很残酷。
但是,我找到了Pattern类里面有一个split的方法,这个方法是一个拆分器。
比如说:我正则写的是匹配数字,但是拆分器会把数字刨除。生成的是["年", "月", "日", "时", "分"]
我要的数字就没了,所以我想到了反向匹配的套路,匹配非数字的字符(串)。
说了一大堆,不上代码怎么行,先来一个反向匹配的代码
1 Pattern pattern = Pattern.compile("[^0-9]+");2 String[] strings = pattern.split("2017年08月18日15时41分");3 System.out.println(Arrays.toString(strings));
运行结果如图:
这种反向匹配也就只能适用于简单的匹配。复杂了,也就不好写了。
于是,在某个夜色的月光下,我痛并快乐着痛定思痛着。So我决定系统的学习一下,看看Java中有没有我要的方法。
参考博客:
再加一个连接:
再附上:
其实看了那个博客我主要学到了这种写法:
1 Pattern p=Pattern.compile("\\d+"); 2 Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com"); 3 while(m.find()) { 4 System.out.println(m.group()); 5 }
这种find和group的写法 有一点像迭代器里面的hashNext和next的方法。
最后就上一下代码吧,要不然整个博客就都跑题了。
题目:统计Java源代码中的关键字。如果关键字在注释或者字符串中,则不进行统计。
1 package setAndMap_Exe; 2 3 import java.io.File; 4 import java.util.Map; 5 import java.util.Scanner; 6 import java.util.Set; 7 import java.util.TreeMap; 8 import java.util.regex.Matcher; 9 import java.util.regex.Pattern;10 11 public class Exe3 {12 public static Mapmap = new TreeMap<>(); 13 14 public static void main(String[] args) throws Exception {15 File file = new File("input.txt");16 String sb = "";17 Scanner input = new Scanner(file);18 while(input.hasNextLine()) {19 sb += input.nextLine() + "\n";20 }21 input.close();22 23 //去除注释 空格 换行符24 Pattern pattern1 = Pattern.compile("//.+");25 Matcher matcher1 = pattern1.matcher(sb);26 sb = matcher1.replaceAll(" ");//去除单行注释27 28 Pattern pattern2 = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL);29 //Pattern.DoTALL这个字段的意思是:可以匹配任何字符,包括行结束符30 // System.out.println(pattern2.toString());31 Matcher matcher2 = pattern2.matcher(sb);32 sb = matcher2.replaceAll(" ");//去除多行注释33 34 //还可以去除换行符 Let's we try it.35 Pattern pattern3 = Pattern.compile("\\n");36 Matcher matcher3 = pattern3.matcher(sb);37 sb = matcher3.replaceAll(" ");//去除换行符38 39 Pattern pattern4 = Pattern.compile("\\t");40 Matcher matcher4 = pattern4.matcher(sb);41 sb = matcher4.replaceAll(" ");//除去制表符42 43 Pattern pattern5 = Pattern.compile("\".+\"");44 Matcher matcher5 = pattern5.matcher(sb);45 sb = matcher5.replaceAll(" ");//出去字符串46 47 // System.out.println(sb); 48 addKeywords();//把关键字加入到Map中 没毛病老铁49 String[] strs = sb.split("[ .,;:!?(){}]");50 //遍历每个单词 如果是关键字就++51 for(int i = 0; i < strs.length; i++) {52 if(map.containsKey(strs[i])) {53 int value = map.get(strs[i]) + 1;54 map.put(strs[i], value);55 }56 }57 58 //遍历一下map 如果value>0 就output59 //当然是用刚刚学的骚套路才行60 Set > set = map.entrySet();61 //然后用foreach遍历62 for(Map.Entry entry : set) {63 if(entry.getValue() > 0) {64 System.out.println(entry.getKey() + ":\t" + entry.getValue());65 }66 }67 }68 69 public static void addKeywords(){70 String[] keywordString = {"abstract", "assert", "boolean",71 "break", "byte", "case", "catch", "char", "class",72 "const", "continue", "default", "do", "double",73 "else", "enum", "extends", "for", "final", "finally",74 "float", "goto", "if", "implements", "import", "instanceof",75 "int", "interface", "long", "native", "new", "package",76 "private", "protected", "public", "return", "short",77 "static", "strictfp", "super", "switch", "synchronized",78 "this", "throw", "throws", "transient", "try",79 "void", "volatile", "while", "true", "false", "null"};80 for(int i = 0; i < keywordString.length; i++) {81 map.put(keywordString[i], 0);82 }83 }84 }85 /**86 * 总结:这个还是有bug的比如:87 * for(int88 * 这样的单词是无法被匹配的。89 * 但是,我想我应该完成书上的练习要求了。90 */
然而bug我好像修复了。
sb是StringBuilder的意思啊。
再附上我测试用的源码(input.txt文件)
1 import java.io.File; 2 import java.util.Scanner; 3 4 public class Main { 5 static int totalLines = 0; 6 public static void main(String[] args) throws Exception{ 7 File file = new File("E:\\mycode"); 8 File[] files = file.listFiles();//将mycode中的文件放到files中 9 fileReader(files);10 System.out.println(totalLines);11 }12 13 public static void fileReader(File[] files) throws Exception{14 for(int i = 0; i < files.length; i++){15 if(files[i].isFile()){16 if(files[i].toString().matches(".*java")){17 totalLines += lines(files[i]);18 }19 }20 else if(files[i].isDirectory())21 fileReader(files[i].listFiles());22 }23 }24 25 public static int lines(File file) throws Exception{26 Scanner scanner = new Scanner(file);27 int lines = 0;28 while(scanner.hasNext())29 {30 scanner.nextLine();31 lines++;32 }33 scanner.close();34 return lines;35 }36 }
这个测试代码是刚开始学File的时候写的一个计算我代码量的代码。