写这个博客主要是稍微系统的学一下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中有没有我要的方法。
参考博客:http://www.cnblogs.com/ggjucheng/p/3423731.html
再加一个连接:http://www.kaiyuanba.cn/html/1/131/138/7609.htm
再附上: 正则表达式30分钟入门教程
其实看了那个博客我主要学到了这种写法:
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 Map<String, Integer> map = 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 就output 59 //当然是用刚刚学的骚套路才行 60 Set<Map.Entry<String, Integer>> set = map.entrySet(); 61 //然后用foreach遍历 62 for(Map.Entry<String, Integer> 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(int 88 * 这样的单词是无法被匹配的。 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的时候写的一个计算我代码量的代码。