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() + "
";
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() + ":	" + 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的时候写的一个计算我代码量的代码。

原文地址:https://www.cnblogs.com/zuosy/p/7390687.html