你的位置:首页 > Java教程

[Java教程]写一个简单的分词器


分词器代码

 1 package www.ygh.fenciqiUtils; 2  3 import java.io.FileReader; 4 import java.util.ArrayList; 5 import java.util.IdentityHashMap; 6 import java.util.List; 7 import java.util.Map; 8 import java.util.Set; 9  10 /** 11  * 最终返回的结果: 12  * 1:表示关键字 13  * 2:普通的非关键字符串 14  * 3:整数(暂不支持小数) 15  * 4:运算符 16  * 5:分隔符 17  * @author Administrator 18  * 19 */ 20 public class CFenCiQi { 21   // 初始化集合list1,用于存在关键字 22   private List<String> list1 = new ArrayList<String>(); 23  24   // 定义集合list4,用于存放运算符号 25   private List<String> list4 = new ArrayList<String>(); 26  27   // 定义集合list5,用于存放分用于存放分隔符号 28   private List<String> list5 = new ArrayList<String>(); 29  30   // 定义集合list3 31   private List<String> list3 = new ArrayList<String>(); 32    33   //"C:\\Users\\Administrator\\Desktop\\test_c.c" 34   private String filePath; 35  36   private List<Map<String, String>> mapList = new ArrayList<Map<String, String>>(); 37  38   private int temp = 0; 39  40   private int match_1 = 0; 41  42   private int match_4 = 0; 43  44   private int match_3 = 0; 45    46   private int ch = 0; 47   private String str1 = ""; 48    49   public CFenCiQi(String filePath) { 50     this.filePath = filePath; 51   } 52    53    54  55   public CFenCiQi() { 56      57   } 58  59  60   /** 61    * 初始化关键字,运算符,分隔符等list集合 62   */ 63   public void init() { 64  65     // 初始化集合list1,用于存在关键字 66     list1.add("if"); 67     list1.add("int"); 68     list1.add("for"); 69     list1.add("while"); 70     list1.add("do"); 71     list1.add("return"); 72     list1.add("break"); 73     list1.add("continue"); 74  75     // 初始化集合list4,用于存放运算符号 76     list4.add("+"); 77     list4.add("-"); 78     list4.add("*"); 79     list4.add("/"); 80     list4.add("="); 81     list4.add(" "); 82     list4.add("<"); 83     list4.add(" ="); 84     list4.add("<="); 85     list4.add("!="); 86  87     // 初始化集合list5,用于存放分隔符号 88     list5.add(","); 89     list5.add(";"); 90     list5.add("{"); 91     list5.add("}"); 92     list5.add("("); 93     list5.add(")"); 94  95     // 初始化集合list3,用于存放数组字符 96     list3.add("0"); 97     list3.add("1"); 98     list3.add("2"); 99     list3.add("3");100     list3.add("4");101     list3.add("5");102     list3.add("6");103     list3.add("7");104     list3.add("8");105     list3.add("9");106 107   }108 109   /**110    * 判断字符是否和运算符匹配111    * @param c112    * @return113   */114   public boolean match_2(String c) {115     for (String str : list4) {116       if (c.equals(str)) {117         return true;118       }119     }120     return false;121   }122 123   /**124    * 判断字符是否和分隔符匹配125    * @param c126    * @return127   */128   public boolean match_4(String c) {129     for (String str : list5) {130       if (c.equals(str)) {131         return true;132       }133     }134     return false;135   }136 137   /**138    * 判断读取的字符是否和数字匹配139    * @param c140    * @return141   */142   public boolean match_3(String c) {143     for (String str : list3) {144       if (c.equals(str)) {145         return true;146       }147     }148     return false;149   }150 151   /**152    * 进行分词153    * @throws Exception154   */155   public void getFenCi() throws Exception {156     157     158     //读取文件的路径159     FileReader fileReader = new FileReader(filePath);160     //挨个读取字符161     while ((ch = fileReader.read()) != -1) {162 163       char c = (char) ch;164       if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {165 166         if (match_4 == 1) {167           matchEqual_4();168         }169 170         if (match_3 == 1) {171           matchEqual_3();172         }173 174         str1 = str1 + c;175         match_1 = 1;176         177       } else if (match_4(c + "")) {178         if(match_1==1){179           matchEqual_1();180         }181 182         if (match_4 == 1) {183           matchEqual_4();184 185         }186 187         if (match_3 == 1) {188           matchEqual_3();189         }190 191         str1 = "";192         str1 = str1 + c;193         setValue("5", str1);194         str1 = "";195 196       } else if (match_2(c + "")) {197         if(match_1==1){198           matchEqual_1();199         }200 201         if (match_3 == 1) {202           matchEqual_3();203         }204 205         str1 = str1 + c;206         match_4 = 1;207 208       } else if (match_3(c + "")) {209         if(match_1==1){210           matchEqual_1();211         }212 213         if (match_4 == 1) {214           matchEqual_4();215         }216 217         str1 = str1 + c;218         match_3 = 1;219       }220     }221     fileReader.close();222   }223 224   /**225    * 设置集合里面的值226    * @param id227    * @param value228   */229   public void setValue(String id, String value) {230     Map<String, String> fenci = new IdentityHashMap<String, String>();231     fenci.put(id, value);232     mapList.add(fenci);233   }234 235   public void matchEqual_1() {236       temp = 0;237       for (String str : list1) {238         if (str.equals(str1)) {239           setValue("1", str1);240           temp = 1;241           break;242         }243       }244 245       if (temp == 0) {246         setValue("2", str1);247       }248 249       match_1 = 0;250       str1 = "";251   }252   253   /**254    * 字符串为数字的处理方法255   */256   public void matchEqual_3() {257     setValue("3", str1);258     match_3 = 0;259     str1 = "";260   }261   262   /**263    * 字符串为运算符的处理方法264   */265   public void matchEqual_4() {266     setValue("4", str1);267     match_4 = 0;268     str1 = "";269   }270 271   272   /**273    * 使用默认的分词器,默认支持c语言274    * @return275    * @throws Exception276   */277   public List<Map<String, String>> getResult() throws Exception {278     //如果没有实现自定义分词,那么就使用默认分词,如果有,实现自定义分词279     if(this.list1==null || this.list4==null || this.list5 ==null){280       init();281     }282     getFenCi();283     return this.mapList;284   }285     286   287   /**288    * 对封装的分词结果进行专业的toSting289    * @param mapList1290   */291   public static void getString(List<Map<String, String>> mapList1){292     for(Map<String, String> map:mapList1){293       Set<String> keySet = map.keySet();294       for(String key:keySet){295         System.out.print("{"+key+"-->"+map.get(key)+"}");296       }297       System.out.print(",");298     }299     System.out.println();300   }301 302   /**303    * 设置需要分词源文件的路径304    * @param filePath305   */306   public void setFilePath(String filePath) {307     this.filePath = filePath;308   }309   310   /**311    * 指定分词的关键字,运算符和分隔符,帮你分词312    * @param keyList 指定关键字的集合313    * @param calculateList   指定运算符集合314    * @param sperateList    指定分隔符集合315   */316   public void setDefaultParam(List<String> keyList,List<String> calculateList,List<String> separateList){317     this.list1 = keyList;318     this.list4 = calculateList;319     this.list5 = separateList;320   }321   322   323 324 }

分词器测试代码

package www.ygh.test;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.junit.Test;import www.ygh.fenciqiUtils.CFenCiQi;public class Test_FenCiQi {  // 初始化集合list1,用于存在关键字  private List<String> list1 = new ArrayList<String>();  // 定义集合list4,用于存放运算符号  private List<String> list4 = new ArrayList<String>();  // 定义集合list5,用于存放分用于存放分隔符号  private List<String> list5 = new ArrayList<String>();  // c语言源代码路径  public String filePath = "C:\\Users\\Administrator\\Desktop\\test_c.c";  // java语言源代码路径  public String filePath2 = "C:\\Users\\Administrator\\Desktop\\fenci.java";  /**   * 使用系统默认的分词,只支持c语言   *   * @throws Exception   */  @Test  public void test_1() throws Exception {    // 创建分词器对象    CFenCiQi cFenCiQi = new CFenCiQi();    // 设置源代码路径    cFenCiQi.setFilePath(filePath);    // 进行分词,并且获取结果    List<Map<String, String>> mapList = cFenCiQi.getResult();    System.out.println(mapList.size());    CFenCiQi.getString(mapList);  }  /**   * 测试自定义的c语言分词   *   * @throws Exception   */  @Test  public void test_2() throws Exception {    //初始化c语言的分词条件    fun1();    // 创建分词器对象    CFenCiQi cFenCiQi = new CFenCiQi();    //把自定义的分词条件传入    cFenCiQi.setDefaultParam(list1, list4, list5);    //传入源代码路径    cFenCiQi.setFilePath(filePath);    List<Map<String, String>> mapList = cFenCiQi.getResult();    CFenCiQi.getString(mapList);  }  /**   * 测试自定义的java的分词   *   * @throws Exception   */  @Test  public void test_3() throws Exception {    fun2();    CFenCiQi cFenCiQi = new CFenCiQi();    cFenCiQi.setDefaultParam(list1, list4, list5);    cFenCiQi.setFilePath(filePath2);    List<Map<String, String>> mapList = cFenCiQi.getResult();    CFenCiQi.getString(mapList);  }  /**   * 初始化c语言分词条件   */  public void fun1() {    // 初始化集合list1,用于存c语言在关键字    list1.add("if");    list1.add("int");    list1.add("for");    list1.add("while");    list1.add("do");    list1.add("return");    list1.add("break");    list1.add("continue");    // 初始化集合list4,用于c语言存放运算符号    list4.add("+");    list4.add("-");    list4.add("*");    list4.add("/");    list4.add("=");    list4.add(" ");    list4.add("<");    list4.add(" =");    list4.add("<=");    list4.add("!=");    // 初始化集合list5,用于存放c语言分隔符号    list5.add(",");    list5.add(";");    list5.add("{");    list5.add("}");    list5.add("(");    list5.add(")");  }  /**   * 初始化java的分词条件   */  public void fun2() {    // 初始化集合list1,用于存在java关键字    list1.add("if");    list1.add("int");    list1.add("for");    list1.add("while");    list1.add("do");    list1.add("return");    list1.add("break");    list1.add("public");    list1.add("class");    list1.add("void");    list1.add("list");    list1.add("out");    list1.add("static");    list1.add("new");    list1.add("char");    list1.add("private");    list1.add("this");    list1.add("import");    list1.add("package");    // 初始化集合list4,用于java存放运算符号    list4.add("+");    list4.add("-");    list4.add("*");    list4.add("/");    list4.add("=");    list4.add(" ");    list4.add("<");    list4.add(" =");    list4.add("<=");    list4.add("!=");    // 初始化集合list5,用于存放java分隔符号    list5.add(",");    list5.add(";");    list5.add("{");    list5.add("}");    list5.add("(");    list5.add(")");  }}

只是一个简单的实现,还有很多不足的地方,希望大家帮忙提提意见,修改修改