// // This software is now distributed according to // the Lesser Gnu Public License. Please see // http://www.gnu.org/copyleft/lesser.txt for // the details. // -- Happy Computing! // package com.stevesoft.pat; import java.io.*; import java.util.*; /** This class is a different form of Regex designed to work more like the file matching utility of a Unix shell. It is implemented by some simple string transformations:
FileRegex Regex
* .*
. \.
{ (?:
{?! (?!
{?= (?=
{?? (??
} )
? .
{,} (|)
Note that a FileRegex pattern always ends with the Regex pattern element "$". If you like to experiment, try making FileRegex's and then printing them out. The toString() method does a decompile of the pattern to a standard Regex. Here are some more complete examples:
FileRegex Regex
*.java .*\.java$
*.{java,html} .*\.(java|html)$
foo.[chC] foo.[chC]$
*/ public class FileRegex extends Regex { /** Build an unitialized FileRegex. */ public FileRegex() { dirflag=EITHER; } /** Build a FileRegex form String s. */ public FileRegex(String s) { super(s); dirflag = EITHER; } /** Compile a new pattern. Throws @exception com.stevesoft.pat.RegSyntax for nonsensical patterns like "[9-0]+" just as Regex does. @see com.stevesoft.pat#compile(java.lang.String) */ public void compile(String s) throws RegSyntax { String npat = toFileRegex(s); super.compile(npat); if(File.separatorChar == '\\') // MS-DOS ignoreCase = true; } /** This is the method required by FileNameFilter. To get a listing of files in the current directory ending in .java, do this:
        File dot = new File(".");
        FileRegex java_files = new FileRegex("*.java");
        String[] file_list = dot.list(java_files);
        
*/ public boolean accept(File dir,String s) { if(dirflag != EITHER) { File f = new File(s); if(f.isDirectory() && dirflag == NONDIR) return false; if(!f.isDirectory() && dirflag == DIR) return false; } return matchAt(s,0); } int dirflag = 0; final static int EITHER=0,DIR=1,NONDIR=2; /** Provides an alternative to File.list -- this separates its argument according to File.pathSeparator. To each path, it splits off a directory -- all characters up to and including the first instance of File.separator -- and a file pattern -- the part that comes after the directory. It then produces a list of all the pattern matches on all the paths. Thus "*.java:../*.java" would produce a list of all the java files in this directory and in the ".." directory on a Unix machine. "*.java;..\\*.java" would do the same thing on a Dos machine. */ public static String[] list(String f) { return list(f,EITHER); } static String[] list(String f,int df) { //return list_(f,new FileRegex()); StringTokenizer st = new StringTokenizer(f,File.pathSeparator); Vector v = new Vector(); while(st.hasMoreTokens()) { String path = st.nextToken(); list1(path,v,df,true); } String[] sa = new String[v.size()]; v.copyInto(sa); return sa; } final static Regex root=new Regex(File.separatorChar=='/' ? "/$" : "(?:.:|)\\\\$"); static void list1(String path,Vector v,int df,boolean rec) { // if path looks like a/b/c/ or d:\ then add . if(root.matchAt(path,0)) { v.addElement(path+"."); return; } File f = new File(path); if(f.getParent() != null && rec) { Vector v2 = new Vector(); list1(f.getParent(),v2,DIR,true); for(int i=0;i