文章记录一下最近看书的一些有关目录搜索的实现,基于java的Pattern,采用正则表达式实现,能够实现基于正则表达式的的目录搜索!
1 String
简单的记载一下java里面的String,因为和之前学习的C++中的string不大一样(一下子想不出来主要些什么,先写一点,以后再补充)
(1)不能被继承:点开源码,可以看到public final class String,String被设置为final;
(2)不能改变:同样看源码,可以看到 private final char value[]; String内部的char字符数组引用被设置为final,也就是value不能指向另外一个新的数组(可能是变大了或者是变小了),这就导致value只能在String被创建的时候被赋值一次。想要反复使用String的字符串相加功能,可以采用StringBuilder,利用append方法添加,最后再toString得到String引用;
(3)split:接触这个Pattern,也是看到了书上讲到String的split函数,看一下源代码,最后都调用了
Pattern.compile(正则表达式).split(待搜索字符串, 分割次数);
结合书上的,这里都和Pattern这个类有关系
2 Pattern
目前对于这个类不是很了解,只是知道这个类的典型用法,这里先简单介绍一下。
(1)static方法compile:根据给定的正则表达式生成相应的Pattern对象;
(2)matcher方法:将Pattern对象与需要搜索的字符串绑定,生成一个Matcher对象,Match对象又包含很多其他的方法。
3 搜索目录
package file;
import java.util.regex.*;
import java.io.File;
public class SearchFile {
private static String[] exceptFiles;
private static int index = 0;
private static int maxchars = 60;
static{
exceptFiles = new String[]{
".*~",
"[.].*",
".*[.]bak",
//".*[.]class",
};
}
public static void search(String filename, String mode, String[] except){
if ( filename==null || mode==null ){
System.out.println("filename or search mode is wrong.");
return;
}
String[][] allExcept= new String[][]{exceptFiles,except};
File f = new File(filename);
if ( f.isFile() )
searchFile(filename, mode, allExcept);
else if ( f.isDirectory() )
searchDirectory(filename, mode, allExcept);
else
System.out.println(filename+" is not a file or directory.");
}
public static void search(String filename, String mode){
search(filename, mode, exceptFiles);
}
private static void searchFile(String filename, String mode, String[][] except){
String name = new File(filename).getName();
for (String r[]:except )
for ( String rule:r ){
if ( name.matches(rule) )
return;
}
Pattern p = Pattern.compile(mode); //创建一个以mode为正则表达式的Pattern对象
Matcher m = p.matcher(""); //将Pattern对象和空字符串绑定
for(String line : new TextFile(filename)) {
m.reset(line); //将Pattern对象与新字符串line绑定
while(m.find()) //在Pattern对象上迭代查找结果
{
String str = "";
int end = 0;
if ( line.length()>maxchars)
{
end = m.start()+maxchars > line.length() ? line.length() : m.start()+maxchars;
str = line.substring(m.start(), end);
}
else
str = line;
System.out.println(++index + ": " +
filename + ": " + str);//group返回匹配串 start返回匹配串在line中的起始索引
}
}
}
private static void searchDirectory(String pathname, String mode, String[][] except){
File[] files = new File(pathname).listFiles();
for (File f:files ){
if (f.isFile())
searchFile(f.getAbsolutePath(), mode, except);
else if ( f.isDirectory() )
searchDirectory(f.getAbsolutePath(), mode, except);
}
}
}
代码本身没有什么复杂的,提供了两个接口search,是两个重载的函数,说明如下:
(1)public static void search(String filename, String mode)
第一个参数,需要搜索的目录或者是文件名称,最好指定绝对路径;
第二个参数,需要匹配的正则表达式,或者直接指定需要搜索的字符串;
(2)public static void search(String filename, String mode, String[] except)
前两个参数意义同上!
第三个参数,不需要进行搜索的文件名类型,这里也只要给定一个文件名的正则表达式即可!
还可以添加一个搜索指定类型文件的接口,这里没有继续添加,以后有用可以再加上!
测试代码如下:
import static file.SearchFile.search;
public class mysearch
{
public static void main(String[] args)
{
String path = System.getProperty("user.dir");
System.out.println(path);
search(path, "main", args);
}
}
编译后运行:
java mysearch ".*[.]class"
上述代码会递归搜索当前目录下除class文件和代码中exceptFiles指定的文件外的所有文件,找到后打印出文件名和所在的行,如果需要搜索指定目录下的指定字符串,可以通过修改测试代码,将main函数的args参数组织如下:
(1)指定目录
(2)指定需要查找的正则表达式或者字符串
(3)一系列需要排除不搜索的文件的正则表达式