寫這個博客主要是稍微系統的學一下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的時候寫的一個計算我代碼量的代碼。
