Java----用正則表達式匹配Java源碼中的關鍵字


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM