zoukankan      html  css  js  c++  java
  • 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的时候写的一个计算我代码量的代码。

  • 相关阅读:
    关于unicode编码问题——[ASIS 2019]Unicorn shop
    cve-2020-7066 ssrf漏洞——GKCTF2020
    updatexml()报错注入——[极客大挑战 2019]HardSQL
    用户名和密码分开检验产生的mysql注入——[GXYCTF2019]BabySQli
    安恒月赛——Ezunserialize(反序列化字符逃逸)
    记一次Flask模板注入学习 [GYCTF2020]FlaskApp
    [CISCN2019 华北赛区 Day2 Web1]Hack World
    [SUCTF 2019]CheckIn(user.ini文件构成的php后门)
    sql注入用<>绕过被过滤的select ——百度杯9月第二场SQL
    剑指offer32 从上到下打印二叉树(叁)
  • 原文地址:https://www.cnblogs.com/zuosy/p/7390687.html
Copyright © 2011-2022 走看看